Browse Source

Merge branch 'release/10.0' of ssh://cloud.finedevelop.com:7999/~hzzz/design61 into release/10.0

master
hzzz 6 years ago
parent
commit
1f335215e0
  1. 41
      designer-base/src/main/java/com/fr/design/beans/FurtherBasicBeanPane.java
  2. 10
      designer-base/src/main/java/com/fr/design/condition/LiteConditionPane.java
  3. 65
      designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java
  4. 363
      designer-base/src/main/java/com/fr/design/gui/icheckbox/UICheckBox.java
  5. 15
      designer-base/src/main/java/com/fr/design/gui/itree/checkboxtree/CheckBoxTreeCellRenderer.java
  6. 14
      designer-base/src/main/java/com/fr/design/gui/itree/checkboxtree/NullTristateCheckBox.java
  7. 201
      designer-base/src/main/java/com/fr/design/gui/itree/checkboxtree/TristateCheckBox.java
  8. 665
      designer-base/src/main/java/com/fr/design/gui/itree/filetree/EnvFileTree.java
  9. 64
      designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileTreeIcon.java
  10. 98
      designer-base/src/main/java/com/fr/design/gui/itree/filetree/TemplateFileTree.java
  11. 51
      designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/ExpandMutableTreeNode.java
  12. 80
      designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/RefreshableJTree.java
  13. 4
      designer-base/src/main/java/com/fr/design/remote/ui/AuthorityEditorPane.java
  14. 126
      designer-base/src/main/java/com/fr/design/remote/ui/UserManagerPane.java
  15. 16
      designer-base/src/main/java/com/fr/design/remote/ui/list/AddedMemberList.java
  16. 2
      designer-base/src/main/java/com/fr/design/remote/ui/list/AddedMemberListCellRender.java
  17. 15
      designer-base/src/main/java/com/fr/design/remote/ui/list/AddingMemberList.java
  18. 13
      designer-base/src/main/java/com/fr/design/remote/ui/list/AddingMemberListCellRender.java
  19. 19
      designer-base/src/main/java/com/fr/design/remote/ui/list/MemberList.java
  20. BIN
      designer-base/src/main/resources/com/fr/design/images/gui/filetree_folder_half_authority_normal.png
  21. 5
      designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java

41
designer-base/src/main/java/com/fr/design/beans/FurtherBasicBeanPane.java

@ -3,30 +3,31 @@ package com.fr.design.beans;
import com.fr.stable.StringUtils;
/**
*
* @author zhou
* @since 2012-5-30下午12:12:42
*/
public abstract class FurtherBasicBeanPane<T> extends BasicBeanPane<T> {
/**
* 是否是指定类型
* @param ob 对象
* @return 是否是指定类型
*/
public abstract boolean accept(Object ob);
/**
* 是否是指定类型
*
* @param ob 对象
* @return 是否是指定类型
*/
public abstract boolean accept(Object ob);
/**
* title应该是一个属性不只是对话框的标题时用到与其他组件结合时也会用得到
* @return 绥化狂标题
*/
@Deprecated
public String title4PopupWindow(){
return StringUtils.EMPTY;
}
/**
* title应该是一个属性不只是对话框的标题时用到与其他组件结合时也会用得到
*
* @return 对话框标题
*/
@Override
public String title4PopupWindow() {
return StringUtils.EMPTY;
}
/**
* 重置
*/
public abstract void reset();
/**
* 重置
*/
public abstract void reset();
}

10
designer-base/src/main/java/com/fr/design/condition/LiteConditionPane.java

@ -857,9 +857,10 @@ public abstract class LiteConditionPane<T extends Condition> extends BasicBeanPa
*/
@Override
public void populateBean(Condition liteCondition) {
if (liteCondition == null){
return;
}
// liteCondition = null 时清空显示
// if (liteCondition == null){
// return;
// }
// peter: 先删除所有的节点
DefaultTreeModel defaultTreeModel = (DefaultTreeModel) this.conditionsTree.getModel();
ExpandMutableTreeNode rootTreeNode = (ExpandMutableTreeNode) defaultTreeModel.getRoot();
@ -900,7 +901,8 @@ public abstract class LiteConditionPane<T extends Condition> extends BasicBeanPa
if (liteCondition == null) {
try {
defaultConditionPane.checkValid();
} catch (Exception e) {//not need
} catch (Exception ignored) {
//not need
}
}
}

65
designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java

@ -23,9 +23,13 @@ import com.fr.stable.StableUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext;
import javax.swing.*;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.ToolTipManager;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
@ -59,9 +63,27 @@ public class TemplateTreePane extends JPanel implements FileOperations {
scrollPane.setBorder(null);
contentPane.add(scrollPane, BorderLayout.CENTER);
this.reportletsTree.addMouseListener(mouseFileTreeListener);// lx: add
// mouse
// listener
/*
* Tree.MouseAdapter
*/
MouseListener mouseFileTreeListener = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent evt) {
if (evt.getClickCount() == 2) {
openSelectedReport();
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (toobarStateChangeListener != null) {
toobarStateChangeListener.stateChange();
}
}
};
// lx: add mouse listener
this.reportletsTree.addMouseListener(mouseFileTreeListener);
this.reportletsTree.addKeyListener(new KeyListener() {
@Override
@ -102,42 +124,21 @@ public class TemplateTreePane extends JPanel implements FileOperations {
reportletsTree.refreshEnv();
}
/*
* Tree.MouseAdapter
*/
MouseListener mouseFileTreeListener = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent evt) {
if (SwingUtilities.isRightMouseButton(evt)) {
return;
} else if (evt.getClickCount() == 2) {
openSelectedReport();
}
}
public void mouseReleased(MouseEvent e) {
if (toobarStateChangeListener != null) {
toobarStateChangeListener.stateChange();
}
}
};
/**
* 打开选中的报表文件
*/
@Override
public void openSelectedReport() {
String reportPath = reportletsTree.getSelectedTemplatePath();
final String selectedFilePath = StableUtils.pathJoin(new String[]{ProjectConstants.REPORTLETS_NAME, reportPath});
final String selectedFilePath = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, reportPath);
DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(selectedFilePath, false)));
}
/**
* 打开文件夹
*/
@Override
public void openContainerFolder() {
FileNode fn = TemplateTreePane.this.reportletsTree.getSelectedFileNode();
String filePath = StableUtils.pathJoin(WorkContext.getCurrent().getPath(), fn.getEnvPath());
@ -152,6 +153,7 @@ public class TemplateTreePane extends JPanel implements FileOperations {
/**
* 刷新
*/
@Override
public void refresh() {
reportletsTree.refresh();
FineLoggerFactory.getLogger().info(Inter.getLocText(new String[]{"File-tree", "Refresh_Successfully"}) + "!");
@ -160,6 +162,7 @@ public class TemplateTreePane extends JPanel implements FileOperations {
/**
* 删除文件
*/
@Override
public void deleteFile() {
String[] reportPaths = reportletsTree.getSelectedTemplatePaths();
if (reportPaths.length == 0) {
@ -169,7 +172,7 @@ public class TemplateTreePane extends JPanel implements FileOperations {
return;
}
for (String reportPath : reportPaths) {
FileNodeFILE nodeFile = new FileNodeFILE(new FileNode(StableUtils.pathJoin(new String[]{ProjectConstants.REPORTLETS_NAME, reportPath}), false));
FileNodeFILE nodeFile = new FileNodeFILE(new FileNode(StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, reportPath), false));
if (nodeFile.isLocked()) {
if (JOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("fileLocked_undeleted"),
@ -227,6 +230,7 @@ public class TemplateTreePane extends JPanel implements FileOperations {
}
@Override
public String getSelectedTemplatePath() {
return reportletsTree.getSelectedTemplatePath();
}
@ -243,6 +247,7 @@ public class TemplateTreePane extends JPanel implements FileOperations {
* @param suffix 后缀名
* @return 是否存在
*/
@Override
public boolean isNameAlreadyExist(String newName, String oldName, String suffix) {
boolean isNameAlreadyExist = false;

363
designer-base/src/main/java/com/fr/design/gui/icheckbox/UICheckBox.java

@ -5,199 +5,198 @@ import com.fr.design.event.GlobalNameListener;
import com.fr.design.event.GlobalNameObserver;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.utils.gui.GUIPaintUtils;
import com.fr.stable.Constants;
import sun.swing.SwingUtilities2;
import javax.swing.*;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.plaf.metal.MetalCheckBoxUI;
import javax.swing.text.View;
import java.awt.*;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
public class UICheckBox extends JCheckBox implements UIObserver, GlobalNameObserver {
private UIObserverListener uiObserverListener;
private GlobalNameListener globalNameListener = null;
private String checkboxName = "";
public UICheckBox(String string) {
super(string);
setUI(new UICheckBoxUI());
initListener();
}
public UICheckBox() {
super();
setUI(new UICheckBoxUI());
initListener();
}
public UICheckBox(String locText, boolean b) {
super(locText, b);
setUI(new UICheckBoxUI());
initListener();
}
public UICheckBox(String text, Icon icon) {
super(text, icon);
setUI(new UICheckBoxUI());
initListener();
}
private void initListener() {
if (shouldResponseChangeListener()) {
this.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (uiObserverListener == null) {
return;
}
if (globalNameListener != null && shouldResponseNameListener()) {
globalNameListener.setGlobalName(checkboxName);
}
uiObserverListener.doChange();
}
});
}
}
/**
* 给组件登记一个观察者监听事件
*
* @param listener 观察者监听事件
*/
public void registerChangeListener(UIObserverListener listener) {
this.uiObserverListener = listener;
}
public void setGlobalName(String name) {
checkboxName = name;
}
/**
* 组件是否需要响应添加的观察者事件
*
* @return 如果需要响应观察者事件则返回true否则返回false
*/
public boolean shouldResponseChangeListener() {
return true;
}
/**
* 注册观察者监听事件
* @param listener 观察者监听事件
*/
public void registerNameListener(GlobalNameListener listener) {
globalNameListener = listener;
}
/**
* 组件是否需要响应观察者事件
* @return 如果需要响应观察者事件则返回true否则返回false
*/
public boolean shouldResponseNameListener() {
return true;
}
private class UICheckBoxUI extends MetalCheckBoxUI {
public void paint(Graphics g, JComponent c) {
synchronized (this) {
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
Dimension size = c.getSize();
Font f = c.getFont();
g.setFont(f);
FontMetrics fm = SwingUtilities2.getFontMetrics(c, g, f);
Rectangle viewRect = new Rectangle(size);
Rectangle iconRect = new Rectangle();
Rectangle textRect = new Rectangle();
Insets i = c.getInsets();
viewRect.x += i.left;
viewRect.y += i.top;
viewRect.width -= (i.right + viewRect.x);
viewRect.height -= (i.bottom + viewRect.y);
Icon altIcon = b.getIcon();
String text = SwingUtilities.layoutCompoundLabel(
c, fm, b.getText(), altIcon != null ? altIcon : getDefaultIcon(),
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
viewRect, iconRect, textRect, b.getIconTextGap());
// fill background
if (c.isOpaque()) {
g.setColor(b.getBackground());
g.fillRect(0, 0, size.width, size.height);
}
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if ( model.isSelected()) {
GUIPaintUtils.fillPaint(g2d, iconRect.x, iconRect.y, iconRect.width, iconRect.height,false, Constants.NULL,
model.isEnabled() ? UIConstants.CHECKBOX_HOVER_SELECTED : UIConstants.DISABLED_ICON_COLOR, 0);
} else if (model.isRollover() && ! model.isSelected()) {
private UIObserverListener uiObserverListener;
private GlobalNameListener globalNameListener = null;
private String checkboxName = "";
public UICheckBox(String string) {
super(string);
setUI(new UICheckBoxUI());
initListener();
}
public UICheckBox() {
super();
setUI(new UICheckBoxUI());
initListener();
}
public UICheckBox(String locText, boolean b) {
super(locText, b);
setUI(new UICheckBoxUI());
initListener();
}
public UICheckBox(String text, Icon icon) {
super(text, icon);
setUI(new UICheckBoxUI());
initListener();
}
private void initListener() {
if (shouldResponseChangeListener()) {
this.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (uiObserverListener == null) {
return;
}
if (globalNameListener != null && shouldResponseNameListener()) {
globalNameListener.setGlobalName(checkboxName);
}
uiObserverListener.doChange();
}
});
}
}
/**
* 给组件登记一个观察者监听事件
*
* @param listener 观察者监听事件
*/
@Override
public void registerChangeListener(UIObserverListener listener) {
this.uiObserverListener = listener;
}
@Override
public void setGlobalName(String name) {
checkboxName = name;
}
/**
* 组件是否需要响应添加的观察者事件
*
* @return 如果需要响应观察者事件则返回true否则返回false
*/
@Override
public boolean shouldResponseChangeListener() {
return true;
}
/**
* 注册观察者监听事件
*
* @param listener 观察者监听事件
*/
@Override
public void registerNameListener(GlobalNameListener listener) {
globalNameListener = listener;
}
/**
* 组件是否需要响应观察者事件
*
* @return 如果需要响应观察者事件则返回true否则返回false
*/
@Override
public boolean shouldResponseNameListener() {
return true;
}
private class UICheckBoxUI extends MetalCheckBoxUI {
@Override
public void paint(Graphics g, JComponent c) {
synchronized (this) {
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
Dimension size = c.getSize();
Font f = c.getFont();
g.setFont(f);
FontMetrics fm = SwingUtilities2.getFontMetrics(c, g, f);
Rectangle viewRect = new Rectangle(size);
Rectangle iconRect = new Rectangle();
Rectangle textRect = new Rectangle();
Insets i = c.getInsets();
viewRect.x += i.left;
viewRect.y += i.top;
viewRect.width -= (i.right + viewRect.x);
viewRect.height -= (i.bottom + viewRect.y);
Icon altIcon = b.getIcon();
String text = SwingUtilities.layoutCompoundLabel(
c, fm, b.getText(), altIcon != null ? altIcon : getDefaultIcon(),
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
viewRect, iconRect, textRect, b.getIconTextGap());
// fill background
if (c.isOpaque()) {
g.setColor(b.getBackground());
g.fillRect(0, 0, size.width, size.height);
}
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (model.isSelected()) {
GUIPaintUtils.fillPaint(g2d, iconRect.x, iconRect.y, iconRect.width, iconRect.height, false, Constants.NULL,
model.isEnabled() ? UIConstants.CHECKBOX_HOVER_SELECTED : UIConstants.DISABLED_ICON_COLOR, 0);
} else if (model.isRollover() && !model.isSelected()) {
g.setColor(UIConstants.CHECKBOX_HOVER_SELECTED);
g2d.drawRoundRect(iconRect.x, iconRect.y, iconRect.width - 1, iconRect.height - 1, UIConstants.ARC, UIConstants.ARC);
}else{
g.setColor(UIConstants.LINE_COLOR);
g2d.drawRoundRect(iconRect.x, iconRect.y, iconRect.width - 1, iconRect.height - 1, UIConstants.ARC, UIConstants.ARC);
}
if (model.isSelected()) {
UIConstants.YES_ICON.paintIcon(c, g, iconRect.x + 2, iconRect.y + 2);
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
// Draw the Text
drawLine(text, g, b, c, textRect, fm);
}
}
private void drawLine(String text, Graphics g, AbstractButton b, JComponent c, Rectangle textRect, FontMetrics fm) {
if (text != null) {
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
if (v != null) {
v.paint(g, textRect);
} else {
int mnemIndex = b.getDisplayedMnemonicIndex();
if (model.isEnabled()) {
g.setColor(b.getForeground());
} else {
g.setColor(getDisabledTextColor());
}
SwingUtilities2.drawStringUnderlineCharAt(c, g, text,
mnemIndex, textRect.x, textRect.y + fm.getAscent());
}
}
}
}
/**
* 测试
* @param args 参数
*/
public static void main(String... args) {
LayoutManager layoutManager = null;
JFrame jf = new JFrame("test");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel content = (JPanel) jf.getContentPane();
content.setLayout(layoutManager);
UICheckBox bb = new UICheckBox("sdf");
bb.setEnabled(false);
bb.setBounds(20, 20, bb.getPreferredSize().width, bb.getPreferredSize().height);
content.add(bb);
GUICoreUtils.centerWindow(jf);
jf.setSize(400, 400);
jf.setVisible(true);
}
} else {
g.setColor(UIConstants.LINE_COLOR);
g2d.drawRoundRect(iconRect.x, iconRect.y, iconRect.width - 1, iconRect.height - 1, UIConstants.ARC, UIConstants.ARC);
}
if (model.isSelected()) {
UIConstants.YES_ICON.paintIcon(c, g, iconRect.x + 2, iconRect.y + 2);
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
// Draw the Text
drawLine(text, g, b, c, textRect, fm);
}
}
private void drawLine(String text, Graphics g, AbstractButton b, JComponent c, Rectangle textRect, FontMetrics fm) {
if (text != null) {
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
if (v != null) {
v.paint(g, textRect);
} else {
int mnemIndex = b.getDisplayedMnemonicIndex();
if (model.isEnabled()) {
g.setColor(b.getForeground());
} else {
g.setColor(getDisabledTextColor());
}
SwingUtilities2.drawStringUnderlineCharAt(c, g, text,
mnemIndex, textRect.x, textRect.y + fm.getAscent());
}
}
}
}
}

15
designer-base/src/main/java/com/fr/design/gui/itree/checkboxtree/CheckBoxTreeCellRenderer.java

@ -10,12 +10,17 @@ import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import javax.swing.*;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JTree;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.io.Serializable;
@ -77,10 +82,10 @@ public class CheckBoxTreeCellRenderer extends NullPanel implements TreeCellRende
_checkBox.setEnabled(((CheckBoxTree) tree).isCheckBoxEnabled() && ((CheckBoxTree) tree).isCheckBoxEnabled(path));
if (selectionModel.isPathSelected(path, selectionModel.isDigIn())) {
_checkBox.setState(TristateCheckBox.SELECTED);
_checkBox.setSelected(true);
} else if (selectionModel.isDigIn() && selectionModel.isPartiallySelected(path)) {
_checkBox.setState(TristateCheckBox.DO_NOT_CARE);
} else {
_checkBox.setState(selectionModel.isDigIn() && selectionModel.isPartiallySelected(path) ? null : TristateCheckBox.NOT_SELECTED);
_checkBox.setSelected(false);
_checkBox.setState(TristateCheckBox.NOT_SELECTED);
}
}
}

14
designer-base/src/main/java/com/fr/design/gui/itree/checkboxtree/NullTristateCheckBox.java

@ -42,10 +42,7 @@ import javax.swing.Icon;
* </code></pre>
*
* @see NullPanel
* @see NullButton
* @see NullJideButton
* @see NullLabel
* @see NullRadioButton
*/
public class NullTristateCheckBox extends TristateCheckBox {
public NullTristateCheckBox() {
@ -63,7 +60,7 @@ public class NullTristateCheckBox extends TristateCheckBox {
super(text, icon, initial);
}
// @Override
@Override
public void updateUI() {
clearAttribute();
}
@ -73,4 +70,13 @@ public class NullTristateCheckBox extends TristateCheckBox {
setBackground(null);
setForeground(null);
}
@Override
protected State getNextState(State current) {
if (SELECTED.equals(current)) {
return NOT_SELECTED;
} else {
return SELECTED;
}
}
}

201
designer-base/src/main/java/com/fr/design/gui/itree/checkboxtree/TristateCheckBox.java

@ -1,28 +1,44 @@
package com.fr.design.gui.itree.checkboxtree;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.utils.gui.GUIPaintUtils;
import com.fr.stable.Constants;
import sun.swing.SwingUtilities2;
import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.ActionMap;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ActionMapUIResource;
import com.fr.design.gui.icheckbox.UICheckBox;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.plaf.metal.MetalCheckBoxUI;
import javax.swing.text.View;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* Maintenance tip - There were some tricks to getting this code
* working:
* <p/>
* 1. You have to overwite addMouseListener() to do nothing
* 1. You have to overwrite addMouseListener() to do nothing
* 2. You have to add a mouse event on mousePressed by calling
* super.addMouseListener()
* 3. You have to replace the UIActionMap for the keyboard event
@ -41,21 +57,30 @@ public class TristateCheckBox extends UICheckBox {
* This is a type-safe enumerated type
*/
public static class State {
private State() {
private String type;
private State(String type) {
this.type = type;
}
@Override
public String toString() {
return this.type;
}
}
public static final State NOT_SELECTED = new State();
public static final State SELECTED = new State();
public static final State DONT_CARE = new State();
public static final State NOT_SELECTED = new State("NOT_SELECTED");
public static final State SELECTED = new State("SELECTED");
public static final State DO_NOT_CARE = new State("DO_NOT_CARE");
private final TristateDecorator model;
public TristateCheckBox(String text, Icon icon, State initial) {
super(text, icon);
setUI(new TristateCheckBoxUI());
// Add a listener for when the mouse is pressed
super.addMouseListener(new MouseAdapter() {
// @Override
@Override
public void mousePressed(MouseEvent e) {
grabFocus();
model.setState(getNextState(model.getState()));
@ -64,6 +89,7 @@ public class TristateCheckBox extends UICheckBox {
// Reset the keyboard action map
ActionMap map = new ActionMapUIResource();
map.put("pressed", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
grabFocus();
model.setState(getNextState(model.getState()));
@ -79,26 +105,29 @@ public class TristateCheckBox extends UICheckBox {
public TristateCheckBox(String text, State initial) {
this(text, null, initial);
setUI(new TristateCheckBoxUI());
}
public TristateCheckBox(String text) {
this(text, DONT_CARE);
this(text, DO_NOT_CARE);
setUI(new TristateCheckBoxUI());
}
public TristateCheckBox() {
this(null);
setUI(new TristateCheckBoxUI());
}
/**
* No one may add mouse listeners, not even Swing!
*/
// @Override
@Override
public void addMouseListener(MouseListener l) {
}
/**
* Set the new state to either SELECTED, NOT_SELECTED or
* DONT_CARE. If state == null, it is treated as DONT_CARE.
* DO_NOT_CARE. If state == null, it is treated as DO_NOT_CARE.
*/
public void setState(State state) {
model.setState(state);
@ -112,15 +141,6 @@ public class TristateCheckBox extends UICheckBox {
return model.getState();
}
// @Override
public void setSelected(boolean b) {
if (b) {
setState(SELECTED);
}
else {
setState(NOT_SELECTED);
}
}
/**
* Exactly which Design Pattern is this? Is it an Adapter,
@ -140,13 +160,13 @@ public class TristateCheckBox extends UICheckBox {
other.setArmed(false);
setPressed(false);
setSelected(false);
}
else if (state == SELECTED) {
} else if (state == SELECTED) {
other.setArmed(false);
setPressed(false);
setSelected(true);
}
else { // either "null" or DONT_CARE
// either "null" or DO_NOT_CARE
else {
other.setArmed(true);
setPressed(true);
setSelected(true);
@ -158,7 +178,7 @@ public class TristateCheckBox extends UICheckBox {
* state of the model.
* <p/>
* We return the SELECTED state when the checkbox is selected
* but not armed, DONT_CARE state when the checkbox is
* but not armed, DO_NOT_CARE state when the checkbox is
* selected and armed (grey) and NOT_SELECTED when the
* checkbox is deselected.
*/
@ -166,12 +186,10 @@ public class TristateCheckBox extends UICheckBox {
if (isSelected() && !isArmed()) {
// normal black tick
return SELECTED;
}
else if (isSelected() && isArmed()) {
} else if (isSelected() && isArmed()) {
// don't care grey tick
return DONT_CARE;
}
else {
return DO_NOT_CARE;
} else {
// normal deselected
return NOT_SELECTED;
}
@ -180,6 +198,7 @@ public class TristateCheckBox extends UICheckBox {
/**
* Filter: No one may change the armed status except us.
*/
@Override
public void setArmed(boolean b) {
}
@ -187,6 +206,7 @@ public class TristateCheckBox extends UICheckBox {
* We disable focusing on the component when it is not
* enabled.
*/
@Override
public void setEnabled(boolean b) {
setFocusable(b);
other.setEnabled(b);
@ -196,89 +216,109 @@ public class TristateCheckBox extends UICheckBox {
* All these methods simply delegate to the "other" model
* that is being decorated.
*/
@Override
public boolean isArmed() {
return other.isArmed();
}
@Override
public boolean isSelected() {
return other.isSelected();
}
@Override
public boolean isEnabled() {
return other.isEnabled();
}
@Override
public boolean isPressed() {
return other.isPressed();
}
@Override
public boolean isRollover() {
return other.isRollover();
}
@Override
public void setSelected(boolean b) {
other.setSelected(b);
}
@Override
public void setPressed(boolean b) {
other.setPressed(b);
}
@Override
public void setRollover(boolean b) {
other.setRollover(b);
}
@Override
public void setMnemonic(int key) {
other.setMnemonic(key);
}
@Override
public int getMnemonic() {
return other.getMnemonic();
}
@Override
public void setActionCommand(String s) {
other.setActionCommand(s);
}
@Override
public String getActionCommand() {
return other.getActionCommand();
}
@Override
public void setGroup(ButtonGroup group) {
other.setGroup(group);
}
@Override
public void addActionListener(ActionListener l) {
other.addActionListener(l);
}
@Override
public void removeActionListener(ActionListener l) {
other.removeActionListener(l);
}
@Override
public void addItemListener(ItemListener l) {
other.addItemListener(l);
}
@Override
public void removeItemListener(ItemListener l) {
other.removeItemListener(l);
}
@Override
public void addChangeListener(ChangeListener l) {
other.addChangeListener(l);
}
@Override
public void removeChangeListener(ChangeListener l) {
other.removeChangeListener(l);
}
@Override
public Object[] getSelectedObjects() {
return other.getSelectedObjects();
}
}
/**
* We rotate between NOT_SELECTED, SELECTED and DONT_CARE. Subclass can
* We rotate between NOT_SELECTED, SELECTED and DO_NOT_CARE. Subclass can
* override this method to tell the check box what next state is. Here is
* the default implementation.
* <code><pre>
@ -286,7 +326,7 @@ public class TristateCheckBox extends UICheckBox {
* return SELECTED;
* }
* else if (current == SELECTED) {
* return DONT_CARE;
* return DO_NOT_CARE;
* }
* else {
* return NOT_SELECTED;
@ -296,12 +336,91 @@ public class TristateCheckBox extends UICheckBox {
protected State getNextState(State current) {
if (current == NOT_SELECTED) {
return SELECTED;
} else if (current == SELECTED) {
return DO_NOT_CARE;
} else {
return NOT_SELECTED;
}
else if (current == SELECTED) {
return DONT_CARE;
}
private class TristateCheckBoxUI extends MetalCheckBoxUI {
@Override
public void paint(Graphics g, JComponent c) {
synchronized (this) {
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
Dimension size = c.getSize();
Font f = c.getFont();
g.setFont(f);
FontMetrics fm = SwingUtilities2.getFontMetrics(c, g, f);
Rectangle viewRect = new Rectangle(size);
Rectangle iconRect = new Rectangle();
Rectangle textRect = new Rectangle();
Insets i = c.getInsets();
viewRect.x += i.left;
viewRect.y += i.top;
viewRect.width -= (i.right + viewRect.x);
viewRect.height -= (i.bottom + viewRect.y);
Icon altIcon = b.getIcon();
String text = SwingUtilities.layoutCompoundLabel(
c, fm, b.getText(), altIcon != null ? altIcon : getDefaultIcon(),
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
viewRect, iconRect, textRect, b.getIconTextGap());
// fill background
if (c.isOpaque()) {
g.setColor(b.getBackground());
g.fillRect(0, 0, size.width, size.height);
}
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (SELECTED.equals(getState())) {
GUIPaintUtils.fillPaint(g2d, iconRect.x, iconRect.y, iconRect.width, iconRect.height, false, Constants.NULL,
model.isEnabled() ? UIConstants.CHECKBOX_HOVER_SELECTED : UIConstants.DISABLED_ICON_COLOR, 0);
} else if (model.isRollover() && !SELECTED.equals(getState())) {
g.setColor(UIConstants.CHECKBOX_HOVER_SELECTED);
g2d.drawRoundRect(iconRect.x, iconRect.y, iconRect.width - 1, iconRect.height - 1, UIConstants.ARC, UIConstants.ARC);
} else {
g.setColor(UIConstants.LINE_COLOR);
g2d.drawRoundRect(iconRect.x, iconRect.y, iconRect.width - 1, iconRect.height - 1, UIConstants.ARC, UIConstants.ARC);
}
if (SELECTED.equals(getState())) {
UIConstants.YES_ICON.paintIcon(c, g, iconRect.x + 2, iconRect.y + 2);
} else if (DO_NOT_CARE.equals(getState())) {
g.setColor(UIConstants.CHECKBOX_HOVER_SELECTED);
g2d.fillRoundRect(iconRect.x + 2, iconRect.y + 2, iconRect.width - 4, iconRect.height - 4, UIConstants.ARC, UIConstants.ARC);
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
// Draw the Text
drawLine(text, g, b, c, textRect, fm);
}
}
else /*if (current == DONT_CARE)*/ {
return NOT_SELECTED;
private void drawLine(String text, Graphics g, AbstractButton b, JComponent c, Rectangle textRect, FontMetrics fm) {
if (text != null) {
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
if (v != null) {
v.paint(g, textRect);
} else {
int mnemIndex = b.getDisplayedMnemonicIndex();
if (model.isEnabled()) {
g.setColor(b.getForeground());
} else {
g.setColor(getDisabledTextColor());
}
SwingUtilities2.drawStringUnderlineCharAt(c, g, text,
mnemIndex, textRect.x, textRect.y + fm.getAscent());
}
}
}
}
}

665
designer-base/src/main/java/com/fr/design/gui/itree/filetree/EnvFileTree.java

@ -8,16 +8,19 @@ import com.fr.design.gui.itree.refreshabletree.RefreshableJTree;
import com.fr.file.filetree.FileNode;
import com.fr.file.filetree.FileNodeFilter;
import com.fr.general.ComparatorUtils;
import com.fr.general.Inter;
import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.CoreConstants;
import com.fr.stable.StableUtils;
import com.fr.workspace.WorkContext;
import javax.swing.*;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
@ -27,330 +30,334 @@ import java.util.Arrays;
*/
public class EnvFileTree extends RefreshableJTree {
protected FileNodeFilter filter;
protected String treeRootPath = "";
protected String[] subPathes;
public EnvFileTree() {
this(null, null);
}
public EnvFileTree(String[] subPathes, FileNodeFilter filter) {
this("", subPathes, filter);
}
public EnvFileTree(String treeRootPath, String[] subPathes, FileNodeFilter filter) {
super(new FileNode(treeRootPath, true));
this.setTreeRootPath(treeRootPath);
this.setFileNodeFilter(filter);
this.setSubPathes(subPathes);
/*一些自己的 init 放在这里,防止直接错误重写了父类的 init 方法导致子类不能使用 CheckBoxTree 的一些特性。*/
this.putClientProperty("JTree.lineStyle", "Angled");
this.setCellRenderer(fileTreeCellRenderer);
this.setRootVisible(false);
this.setShowsRootHandles(true);
this.setEditable(false);
}
private void setTreeRootPath(String path) {
if (path == null) {
path = "";
}
this.treeRootPath = path;
}
public void setFileNodeFilter(FileNodeFilter filter) {
this.filter = filter;
}
// CellRenderer
private DefaultTreeCellRenderer fileTreeCellRenderer = new DefaultTreeCellRenderer() {
@Override
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);
ExpandMutableTreeNode treeNode = (ExpandMutableTreeNode) value;
Object userObj = treeNode.getUserObject();
if (userObj instanceof FileNode) {
FileNode node = (FileNode) userObj;
String lock = node.getLock();
String name = node.getName();
if (lock != null && !node.getUserID().equals(lock)) {
name = name + Inter.getLocText("Locked");
this.setIcon(FileTreeIcon.getIcon(node));
}else {
this.setIcon(FileTreeIcon.getIcon(node, false));
}
this.setText(name);
} else if (userObj == PENDING) {
this.setIcon(null);
this.setText(PENDING.toString());
}
// 这里新建一个Label作为render是因为JTree在动态刷新的时候,节点上render画布的的宽度不会变,会使得一部分比较长的数据显示为"..."
UILabel label = new UILabel();
label.setText(getText());
label.setIcon(getIcon());
this.setSize(label.getPreferredSize());
Dimension dim = label.getPreferredSize();
dim.height += 2;
this.setPreferredSize(dim);
this.setBackgroundNonSelectionColor(UIConstants.TREE_BACKGROUND);
this.setTextSelectionColor(Color.WHITE);
this.setBackgroundSelectionColor(UIConstants.FLESH_BLUE);
return this;
}
};
/*
* 在当前tree中选中currentPath
*/
public void selectPath(String currentPath) {
if (currentPath == null) {
return;
}
DefaultTreeModel m_model = (DefaultTreeModel) this.getModel();
ExpandMutableTreeNode treeNode = (ExpandMutableTreeNode) m_model.getRoot();
for (int i = 0, len = treeNode.getChildCount(); i < len; i++) {
// 取出当前的childTreeNode,并append到searchingPath后面
ExpandMutableTreeNode childTreeNode = (ExpandMutableTreeNode) treeNode.getChildAt(i);
if (selectFilePath(childTreeNode, "", currentPath, m_model)) {
break;
}
}
TreePath selectedTreePath = this.getSelectionPath();
if (selectedTreePath != null) {
this.scrollPathToVisible(selectedTreePath);
}
}
/*
* 在currentTreeNode下找寻filePath
*
* prefix + currentTreeNode.getName() = currentTreeNode所对应的Path
*
* 返回currentTreeNode下是否找到了filePath
*/
private boolean selectFilePath(ExpandMutableTreeNode currentTreeNode, String prefix, String filePath, DefaultTreeModel m_model) {
FileNode fileNode = (FileNode) currentTreeNode.getUserObject();
String nodePath = fileNode.getName();
String currentTreePath = prefix + nodePath;
// 如果equals,说明找到了,不必再找下去了
if (ComparatorUtils.equals(new File(currentTreePath), new File(filePath))) {
this.setSelectionPath(new TreePath(m_model.getPathToRoot(currentTreeNode)));
return true;
} // 如果当前路径是currentFilePath的ParnetFile,则expandTreeNode,并继续往下找
else if (EnvFileTree.isParentFile(currentTreePath, filePath)) {
this.loadPendingChildTreeNode(currentTreeNode);
prefix = currentTreePath + CoreConstants.SEPARATOR;
for (int i = 0, len = currentTreeNode.getChildCount(); i < len; i++) {
ExpandMutableTreeNode childTreeNode = (ExpandMutableTreeNode) currentTreeNode.getChildAt(i);
if (selectFilePath(childTreeNode, prefix, filePath, m_model)) {
return true;
}
}
return false;
}
return false;
}
/*
* 求当前TreeNode下所有的FileNode.
*/
private FileNode[] listFileNodes(ExpandMutableTreeNode currentTreeNode) {
if (currentTreeNode == null) {
return new FileNode[0];
}
Object object = currentTreeNode.getUserObject();
if (object instanceof FileNode) {
return this.listFileNodes(((FileNode) object).getEnvPath());
}
return new FileNode[0];
}
/*
* 求filePath这个String,求其路径下面的所有的FileNode
*/
private FileNode[] listFileNodes(String filePath) {
FileNode[] res_fns = null;
try {
res_fns = WorkContext.getCurrent() == null ? new FileNode[0] : FRContext.getFileNodes().list(filePath);
} catch (Exception e) {
FRContext.getLogger().error(e.getMessage(), e);
}
if (res_fns == null) {
res_fns = new FileNode[0];
}
// 用FileNodeFilter过滤一下
if (filter != null) {
java.util.List<FileNode> t_list = new ArrayList<FileNode>();
for (int i = 0; i < res_fns.length; i++) {
if (filter.accept(res_fns[i])) {
t_list.add(res_fns[i]);
}
}
res_fns = t_list.toArray(new FileNode[t_list.size()]);
}
Arrays.sort(res_fns, new FileNodeComparator());
return res_fns;
}
/*
* 获取当前选中的FilePath的String,这个FilePath是需要拼起来的
*/
public FileNode getSelectedFileNode() {
TreePath selectedTreePath = this.getSelectionPath();
if (selectedTreePath == null) {
return null;
}
ExpandMutableTreeNode currentTreeNode = (ExpandMutableTreeNode) selectedTreePath.getLastPathComponent();
Object userObject = currentTreeNode.getUserObject();
if (userObject instanceof FileNode) {
return (FileNode) userObject;
}
return null;
}
/*
* 改变Env后,根据构造函数时设置的RootPathes,重新加载
*/
public void refreshEnv() {
DefaultTreeModel m_model = (DefaultTreeModel) this.getModel();
ExpandMutableTreeNode rootTreeNode = (ExpandMutableTreeNode) m_model.getRoot();
rootTreeNode.removeAllChildren();
FileNode[] fns;
// 如果rootPaths是null的话列出所有文件
if (subPathes == null) {
fns = listFileNodes(this.treeRootPath);
} else {
// 重新加载新的FileDirectoryNode
fns = new FileNode[subPathes.length];
for (int i = 0; i < subPathes.length; i++) {
fns[i] = new FileNode(StableUtils.pathJoin(new String[]{this.treeRootPath, subPathes[i]}), true);
}
}
ExpandMutableTreeNode[] sub_tree_node_array = fileNodeArray2TreeNodeArray(fns);
for (int i = 0; i < sub_tree_node_array.length; i++) {
ExpandMutableTreeNode node = sub_tree_node_array[i];
rootTreeNode.add(node);
}
m_model.reload(rootTreeNode);
}
/*
* 设置当前Tree的rootPathes
*/
private void setSubPathes(String[] subPathes) {
this.subPathes = subPathes;
}
/**
* currentTreeNode下面如果是PENDING的节点,加载之...
*/
protected void loadPendingChildTreeNode(ExpandMutableTreeNode currentTreeNode) {
if (currentTreeNode.isLeaf()) {
return;
}
// 判断第一个孩子节点.UserObject是不是PENDING,如果是PENDING的话,需要重新加载这个TreeNode
ExpandMutableTreeNode flag = (ExpandMutableTreeNode) currentTreeNode.getFirstChild();
if (flag == null || flag.getUserObject() != PENDING) {
return;
}
currentTreeNode.removeAllChildren(); // 删除所有的节点.
ExpandMutableTreeNode[] children = loadChildTreeNodes(currentTreeNode);
for (ExpandMutableTreeNode c : children) {
currentTreeNode.add(c);
}
}
/*
* 判断eTreeNode是否需要Refresh,可提前中止,返回true则表示提前中止,不需要Refresh
*/
protected boolean interceptRefresh(ExpandMutableTreeNode eTreeNode) {
Object userObject = eTreeNode.getUserObject();
if (userObject instanceof FileNode && !((FileNode) userObject).isDirectory()) {
return true;
}
return eTreeNode.getChildCount() == 1 && ((ExpandMutableTreeNode) eTreeNode.getFirstChild()).getUserObject() == PENDING;
}
/*
* 得到treeNode的子节点ExpandMutableTreeNode的数组
*/
protected ExpandMutableTreeNode[] loadChildTreeNodes(ExpandMutableTreeNode treeNode) {
FileNode[] fn_array = listFileNodes(treeNode);
return fileNodeArray2TreeNodeArray(fn_array);
}
/*
* 把FileNode[]转成ExpandMutableTreeNode[]
*/
private ExpandMutableTreeNode[] fileNodeArray2TreeNodeArray(FileNode[] fn_array) {
ExpandMutableTreeNode[] res = new ExpandMutableTreeNode[fn_array.length];
for (int i = 0; i < res.length; i++) {
FileNode fn = fn_array[i];
res[i] = new ExpandMutableTreeNode(fn);
if (fn.isDirectory()) {
res[i].add(new ExpandMutableTreeNode());
}
}
return res;
}
/*
* 是否是父子关系的文件.
*/
protected static boolean isParentFile(String parentFilePath, String childFilePath) {
File parentFile = new File(parentFilePath);
File childFile = new File(childFilePath);
while (true) {
if (ComparatorUtils.equals(parentFile, childFile)) {
return true;
}
childFile = childFile.getParentFile();
if (childFile == null) {
break;
}
}
return false;
}
protected FileNodeFilter filter;
protected String treeRootPath = "";
protected String[] subPaths;
public EnvFileTree() {
this(null, null);
}
public EnvFileTree(String[] subPaths, FileNodeFilter filter) {
this("", subPaths, filter);
}
public EnvFileTree(String treeRootPath, String[] subPaths, FileNodeFilter filter) {
super(new FileNode(treeRootPath, true));
this.setTreeRootPath(treeRootPath);
this.setFileNodeFilter(filter);
this.setSubPaths(subPaths);
/*一些自己的 init 放在这里,防止直接错误重写了父类的 init 方法导致子类不能使用 CheckBoxTree 的一些特性。*/
this.putClientProperty("JTree.lineStyle", "Angled");
// CellRenderer
// 这里新建一个Label作为render是因为JTree在动态刷新的时候,节点上render画布的的宽度不会变,会使得一部分比较长的数据显示为
DefaultTreeCellRenderer fileTreeCellRenderer = new DefaultTreeCellRenderer() {
@Override
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);
ExpandMutableTreeNode treeNode = (ExpandMutableTreeNode) value;
Object userObj = treeNode.getUserObject();
if (userObj instanceof FileNode) {
FileNode node = (FileNode) userObj;
String lock = node.getLock();
String name = node.getName();
if (treeNode.hasFullAuthority()) {
if (lock != null && !node.getUserID().equals(lock)) {
name = name + InterProviderFactory.getProvider().getLocText("Locked");
this.setIcon(FileTreeIcon.getIcon(node));
} else {
this.setIcon(FileTreeIcon.getIcon(node, false));
}
} else {
this.setIcon(FileTreeIcon.getFolderHalfImageIcon());
}
this.setText(name);
} else if (userObj == PENDING) {
this.setIcon(null);
this.setText(PENDING.toString());
}
// 这里新建一个Label作为render是因为JTree在动态刷新的时候,节点上render画布的的宽度不会变,会使得一部分比较长的数据显示为"..."
UILabel label = new UILabel();
label.setText(getText());
label.setIcon(getIcon());
this.setSize(label.getPreferredSize());
Dimension dim = label.getPreferredSize();
dim.height += 2;
this.setPreferredSize(dim);
this.setBackgroundNonSelectionColor(UIConstants.TREE_BACKGROUND);
this.setTextSelectionColor(Color.WHITE);
this.setBackgroundSelectionColor(UIConstants.FLESH_BLUE);
return this;
}
};
this.setCellRenderer(fileTreeCellRenderer);
this.setRootVisible(false);
this.setShowsRootHandles(true);
this.setEditable(false);
}
private void setTreeRootPath(String path) {
if (path == null) {
path = "";
}
this.treeRootPath = path;
}
public void setFileNodeFilter(FileNodeFilter filter) {
this.filter = filter;
}
/*
* 在当前tree中选中currentPath
*/
public void selectPath(String currentPath) {
if (currentPath == null) {
return;
}
DefaultTreeModel m_model = (DefaultTreeModel) this.getModel();
ExpandMutableTreeNode treeNode = (ExpandMutableTreeNode) m_model.getRoot();
for (int i = 0, len = treeNode.getChildCount(); i < len; i++) {
// 取出当前的childTreeNode,并append到searchingPath后面
ExpandMutableTreeNode childTreeNode = (ExpandMutableTreeNode) treeNode.getChildAt(i);
if (selectFilePath(childTreeNode, "", currentPath, m_model)) {
break;
}
}
TreePath selectedTreePath = this.getSelectionPath();
if (selectedTreePath != null) {
this.scrollPathToVisible(selectedTreePath);
}
}
/*
* 在currentTreeNode下找寻filePath
*
* prefix + currentTreeNode.getName() = currentTreeNode所对应的Path
*
* 返回currentTreeNode下是否找到了filePath
*/
private boolean selectFilePath(ExpandMutableTreeNode currentTreeNode, String prefix, String filePath, DefaultTreeModel m_model) {
FileNode fileNode = (FileNode) currentTreeNode.getUserObject();
String nodePath = fileNode.getName();
String currentTreePath = prefix + nodePath;
// 如果equals,说明找到了,不必再找下去了
if (ComparatorUtils.equals(new File(currentTreePath), new File(filePath))) {
this.setSelectionPath(new TreePath(m_model.getPathToRoot(currentTreeNode)));
return true;
}
// 如果当前路径是currentFilePath的ParentFile,则expandTreeNode,并继续往下找
else if (EnvFileTree.isParentFile(currentTreePath, filePath)) {
this.loadPendingChildTreeNode(currentTreeNode);
prefix = currentTreePath + CoreConstants.SEPARATOR;
for (int i = 0, len = currentTreeNode.getChildCount(); i < len; i++) {
ExpandMutableTreeNode childTreeNode = (ExpandMutableTreeNode) currentTreeNode.getChildAt(i);
if (selectFilePath(childTreeNode, prefix, filePath, m_model)) {
return true;
}
}
return false;
}
return false;
}
/*
* 求当前TreeNode下所有的FileNode.
*/
private FileNode[] listFileNodes(ExpandMutableTreeNode currentTreeNode) {
if (currentTreeNode == null) {
return new FileNode[0];
}
Object object = currentTreeNode.getUserObject();
if (object instanceof FileNode) {
return this.listFileNodes(((FileNode) object).getEnvPath());
}
return new FileNode[0];
}
/*
* 求filePath这个String,求其路径下面的所有的FileNode
*/
private FileNode[] listFileNodes(String filePath) {
FileNode[] resFns = null;
try {
resFns = WorkContext.getCurrent() == null ? new FileNode[0] : FRContext.getFileNodes().list(filePath);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
if (resFns == null) {
resFns = new FileNode[0];
}
// 用FileNodeFilter过滤一下
if (filter != null) {
java.util.List<FileNode> tList = new ArrayList<FileNode>();
for (int i = 0; i < resFns.length; i++) {
if (filter.accept(resFns[i])) {
tList.add(resFns[i]);
}
}
resFns = tList.toArray(new FileNode[tList.size()]);
}
Arrays.sort(resFns, new FileNodeComparator());
return resFns;
}
/*
* 获取当前选中的FilePath的String,这个FilePath是需要拼起来的
*/
public FileNode getSelectedFileNode() {
TreePath selectedTreePath = this.getSelectionPath();
if (selectedTreePath == null) {
return null;
}
ExpandMutableTreeNode currentTreeNode = (ExpandMutableTreeNode) selectedTreePath.getLastPathComponent();
Object userObject = currentTreeNode.getUserObject();
if (userObject instanceof FileNode) {
return (FileNode) userObject;
}
return null;
}
/*
* 改变Env后,根据构造函数时设置的RootPaths,重新加载
*/
public void refreshEnv() {
DefaultTreeModel m_model = (DefaultTreeModel) this.getModel();
ExpandMutableTreeNode rootTreeNode = (ExpandMutableTreeNode) m_model.getRoot();
rootTreeNode.removeAllChildren();
FileNode[] fns;
// 如果rootPaths是null的话列出所有文件
if (subPaths == null) {
fns = listFileNodes(this.treeRootPath);
} else {
// 重新加载新的FileDirectoryNode
fns = new FileNode[subPaths.length];
for (int i = 0; i < subPaths.length; i++) {
fns[i] = new FileNode(StableUtils.pathJoin(this.treeRootPath, subPaths[i]), true);
}
}
ExpandMutableTreeNode[] subTreeNodeArray = fileNodeArray2TreeNodeArray(fns);
for (int i = 0; i < subTreeNodeArray.length; i++) {
ExpandMutableTreeNode node = subTreeNodeArray[i];
rootTreeNode.add(node);
}
m_model.reload(rootTreeNode);
}
/*
* 设置当前Tree的rootPaths
*/
private void setSubPaths(String[] subPaths) {
this.subPaths = subPaths;
}
/**
* currentTreeNode下面如果是PENDING的节点,加载之...
*/
protected void loadPendingChildTreeNode(ExpandMutableTreeNode currentTreeNode) {
if (currentTreeNode.isLeaf()) {
return;
}
// 判断第一个孩子节点.UserObject是不是PENDING,如果是PENDING的话,需要重新加载这个TreeNode
ExpandMutableTreeNode flag = (ExpandMutableTreeNode) currentTreeNode.getFirstChild();
if (flag == null || flag.getUserObject() != PENDING) {
return;
}
// 删除所有的节点.
currentTreeNode.removeAllChildren();
ExpandMutableTreeNode[] children = loadChildTreeNodes(currentTreeNode);
for (ExpandMutableTreeNode c : children) {
currentTreeNode.add(c);
}
}
/*
* 判断eTreeNode是否需要Refresh,可提前中止,返回true则表示提前中止,不需要Refresh
*/
@Override
protected boolean interceptRefresh(ExpandMutableTreeNode eTreeNode) {
Object userObject = eTreeNode.getUserObject();
if (userObject instanceof FileNode && !((FileNode) userObject).isDirectory()) {
return true;
}
return eTreeNode.getChildCount() == 1 && ((ExpandMutableTreeNode) eTreeNode.getFirstChild()).getUserObject() == PENDING;
}
/*
* 得到treeNode的子节点ExpandMutableTreeNode的数组
*/
@Override
protected ExpandMutableTreeNode[] loadChildTreeNodes(ExpandMutableTreeNode treeNode) {
FileNode[] fnArray = listFileNodes(treeNode);
return fileNodeArray2TreeNodeArray(fnArray);
}
/*
* 把FileNode[]转成ExpandMutableTreeNode[]
*/
private ExpandMutableTreeNode[] fileNodeArray2TreeNodeArray(FileNode[] fn_array) {
ExpandMutableTreeNode[] res = new ExpandMutableTreeNode[fn_array.length];
for (int i = 0; i < res.length; i++) {
FileNode fn = fn_array[i];
res[i] = new ExpandMutableTreeNode(fn);
if (fn.isDirectory()) {
res[i].add(new ExpandMutableTreeNode());
}
}
return res;
}
/*
* 是否是父子关系的文件.
*/
protected static boolean isParentFile(String parentFilePath, String childFilePath) {
File parentFile = new File(parentFilePath);
File childFile = new File(childFilePath);
do {
if (ComparatorUtils.equals(parentFile, childFile)) {
return true;
}
childFile = childFile.getParentFile();
} while (childFile != null);
return false;
}
}

64
designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileTreeIcon.java

@ -1,22 +1,26 @@
package com.fr.design.gui.itree.filetree;
import com.fr.base.BaseUtils;
import com.fr.base.FRContext;
import com.fr.design.icon.LockIcon;
import com.fr.file.filetree.FileNode;
import com.fr.stable.StableUtils;
import com.fr.workspace.WorkContext;
import javax.swing.*;
import javax.swing.Icon;
import javax.swing.UIManager;
import javax.swing.filechooser.FileSystemView;
import java.io.File;
public class FileTreeIcon {
private FileTreeIcon() {}
private FileTreeIcon() {
}
public static final Icon BLANK_IMAGE_ICON = BaseUtils.readIcon("/com/fr/design/images/gui/blank.gif");
public static final Icon FOLDER_IMAGE_ICON = BaseUtils.readIcon("/com/fr/design/images/gui/folder.png");
public static final Icon FOLDER_IMAGE_ICON = BaseUtils.readIcon("/com/fr/design/images/gui/folder.png");
public static final Icon FOLDER_HALF_IMAGE_ICON =
BaseUtils.readIcon("/com/fr/design/images/gui/filetree_folder_half_authority_normal.png");
public static final Icon FILE_IMAGE_ICON = UIManager.getIcon("FileView.fileIcon");
public static final Icon JAVA_FILE_IMAGE_ICON = BaseUtils.readIcon("/com/fr/design/images/gui/javaFile.gif");
@ -63,9 +67,9 @@ public class FileTreeIcon {
public static final LockIcon CPT_FILE_LOCK_ICON =
new LockIcon(BaseUtils.readImage("/com/fr/base/images/oem/cptlocked.png"));
public static final LockIcon FRM_FILE_LOCK_ICON =
new LockIcon(BaseUtils.readImage("/com/fr/design/images/gui/frmlocked.png"));
new LockIcon(BaseUtils.readImage("/com/fr/design/images/gui/frmlocked.png"));
public static final LockIcon CHT_FILE_LOCK_ICON =
new LockIcon(BaseUtils.readImage("/com/fr/design/images/gui/frmlocked.png"));
new LockIcon(BaseUtils.readImage("/com/fr/design/images/gui/frmlocked.png"));
/**
* file types
*/
@ -109,27 +113,31 @@ public class FileTreeIcon {
return FileTreeIcon.getIcon(FileTreeIcon.getFileType(file.getName()), isLocked);
}
public static Icon getIcon(FileNode node) {
return getIcon(node, node.getLock() != null);
public static Icon getFolderHalfImageIcon() {
return FOLDER_HALF_IMAGE_ICON;
}
public static Icon getIcon(FileNode node) {
return getIcon(node, node.getLock() != null);
}
public static Icon getIcon(FileNode node, boolean isShowLock) {
String path = StableUtils.pathJoin(new String[]{WorkContext.getCurrent().getPath(), node.getEnvPath()});
String path = StableUtils.pathJoin(WorkContext.getCurrent().getPath(), node.getEnvPath());
if (WorkContext.getCurrent().isLocal()) {
File ff = new File(path);
if (ff.exists()) {
if(node.isDirectory()){
if (node.isDirectory()) {
return FileTreeIcon.FOLDER_IMAGE_ICON;
}
return FileSystemView.getFileSystemView().getSystemIcon(new File(path));
}
}
if(node.isDirectory()) {
return FileTreeIcon.FOLDER_IMAGE_ICON;
} else {
return FileTreeIcon.getIcon(FileTreeIcon.getFileType(node.getName()), isShowLock);
}
if (node.isDirectory()) {
return FileTreeIcon.FOLDER_IMAGE_ICON;
} else {
return FileTreeIcon.getIcon(FileTreeIcon.getFileType(node.getName()), isShowLock);
}
}
private static Icon getIcon(int fileType, boolean isLocked) {
@ -200,13 +208,13 @@ public class FileTreeIcon {
return FileTreeIcon.CPT_FILE_IMAGE_ICON;
}
} else if (fileType == FRM_FILE) { //form frm
if (isLocked) {
if (isLocked) {
return FileTreeIcon.FRM_FILE_LOCK_ICON;
} else {
return FileTreeIcon.FRM_FILE_IMAGE_ICON;
}
} else if (fileType == CHT_FILE) { //chart cht
if (isLocked) {
if (isLocked) {
return FileTreeIcon.CHT_FILE_LOCK_ICON;
} else {
return FileTreeIcon.CHT_FILE_IMAGE_ICON;
@ -249,22 +257,22 @@ public class FileTreeIcon {
return CLASS_FILE;
} else if (fileName.endsWith(".jar") || fileName.endsWith(".zip")) {
return ZIP_FILE;
} else if( fileName.endsWith(".ear") || fileName.endsWith(".war")){
} else if (fileName.endsWith(".ear") || fileName.endsWith(".war")) {
return ZIP_FILE;
}else if (fileName.endsWith(".gif")) {
} else if (fileName.endsWith(".gif")) {
return GIF_FILE;
} else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpe")) {
return JPG_FILE;
} else if( fileName.endsWith(".jpeg")){
} else if (fileName.endsWith(".jpeg")) {
return JPG_FILE;
}else if (fileName.endsWith(".bmp")) {
} else if (fileName.endsWith(".bmp")) {
return BMP_FILE;
} else if (fileName.endsWith(".cpt")) {
return CPT_FILE;
} else if (fileName.endsWith(".frm") || fileName.endsWith(".form")){
return FRM_FILE;
} else if (fileName.endsWith(".cht") || fileName.endsWith(".chart")){
return CHT_FILE;
} else if (fileName.endsWith(".frm") || fileName.endsWith(".form")) {
return FRM_FILE;
} else if (fileName.endsWith(".cht") || fileName.endsWith(".chart")) {
return CHT_FILE;
} else {
return TEXT_FILE;
}

98
designer-base/src/main/java/com/fr/design/gui/itree/filetree/TemplateFileTree.java

@ -4,10 +4,15 @@ import com.fr.base.FRContext;
import com.fr.base.extension.FileExtension;
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode;
import com.fr.file.filetree.FileNode;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.report.DesignAuthority;
import com.fr.stable.ArrayUtils;
import com.fr.stable.CoreConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.authority.AuthorityOperator;
import javax.swing.text.Position;
import javax.swing.tree.DefaultTreeModel;
@ -22,6 +27,11 @@ import java.util.List;
public class TemplateFileTree extends EnvFileTree {
/**
* 远程设计拥有全部权限的文件夹路径
*/
private ArrayList<String> paths = new ArrayList<>();
public TemplateFileTree() {
super(ProjectConstants.REPORTLETS_NAME, null, null);
}
@ -73,6 +83,7 @@ public class TemplateFileTree extends EnvFileTree {
return selectedPathList.toArray(new String[0]);
}
@Override
public TreePath getNextMatch(String prefix, int startingRow, Position.Bias bias) {
int max = getRowCount();
@ -100,16 +111,45 @@ public class TemplateFileTree extends EnvFileTree {
return null;
}
public FileNode[] listFile(String path) throws Exception {
public FileNode[] listFile(String path) {
return FRContext.getFileNodes().list(
path,
new FileExtension[]{FileExtension.CPT, FileExtension.FRM, FileExtension.CHT,FileExtension.XLS,FileExtension.XLSX});
new FileExtension[]{FileExtension.CPT, FileExtension.FRM, FileExtension.CHT, FileExtension.XLS, FileExtension.XLSX});
}
/*
* 改变Env后,根据构造函数时设置的RootPaths,重新加载
*/
@Override
public void refreshEnv() {
paths.clear();
if (!WorkContext.getCurrent().isLocal()) {
try {
String username = WorkContext.getConnector().currentUser();
// 远程设计获取全部设计成员的权限列表
DesignAuthority[] authorities = WorkContext.getCurrent().get(AuthorityOperator.class).getAuthorities();
DesignAuthority authority = null;
if (authorities != null) {
for (DesignAuthority designAuthority : authorities) {
if (ComparatorUtils.equals(designAuthority.getUsername(), username)) {
authority = designAuthority;
}
}
}
if (authority != null) {
for (DesignAuthority.Item item : authority.getItems()) {
if (item.getType()) {
paths.add(item.getPath());
}
}
}
} catch (Exception exception) {
FineLoggerFactory.getLogger().error(exception.getMessage(), exception);
}
}
DefaultTreeModel defaultTreeModel = (DefaultTreeModel) this.getModel();
ExpandMutableTreeNode rootTreeNode = (ExpandMutableTreeNode) defaultTreeModel.getRoot();
@ -118,13 +158,13 @@ public class TemplateFileTree extends EnvFileTree {
FileNode[] fns;
// 如果rootPaths是null的话列出所有文件
if (subPathes == null) {
if (subPaths == null) {
fns = listFileNodes(this.treeRootPath);
} else {
// 重新加载新的FileDirectoryNode
fns = new FileNode[subPathes.length];
for (int i = 0; i < subPathes.length; i++) {
fns[i] = new FileNode(StableUtils.pathJoin(this.treeRootPath, subPathes[i]), true);
fns = new FileNode[subPaths.length];
for (int i = 0; i < subPaths.length; i++) {
fns[i] = new FileNode(StableUtils.pathJoin(this.treeRootPath, subPaths[i]), true);
}
}
@ -137,28 +177,70 @@ public class TemplateFileTree extends EnvFileTree {
defaultTreeModel.reload(rootTreeNode);
}
@Override
protected ExpandMutableTreeNode[] loadChildTreeNodes(ExpandMutableTreeNode treeNode) {
FileNode[] fn_array = listFileNodes(treeNode);
FileNode[] fnArray = listFileNodes(treeNode);
return fileNodeArray2TreeNodeArray(fn_array);
return fileNodeArray2TreeNodeArray(fnArray);
}
/*
* 把FileNode[]转成ExpandMutableTreeNode[]
*/
private ExpandMutableTreeNode[] fileNodeArray2TreeNodeArray(FileNode[] fileNodes) {
boolean isLocal = WorkContext.getCurrent().isLocal();
ExpandMutableTreeNode[] res = new ExpandMutableTreeNode[fileNodes.length];
for (int i = 0; i < res.length; i++) {
FileNode fn = fileNodes[i];
res[i] = new ExpandMutableTreeNode(fn);
if (fn.isDirectory()) {
res[i].add(new ExpandMutableTreeNode());
if (isLocal || WorkContext.getCurrent().isRoot()) {
res[i].setFullAuthority(true);
} else {
boolean hasFullAuthority = isContained(fn);
res[i].setFullAuthority(hasFullAuthority);
}
}
}
return res;
}
private boolean isContained(FileNode fileNode) {
for (String auPath : paths) {
if (isContained(auPath, fileNode)) {
return true;
}
}
return false;
}
private boolean isContained(String auPath, FileNode fileNode) {
auPath = ProjectConstants.REPORTLETS_NAME + CoreConstants.SEPARATOR + auPath;
String fileName = fileNode.getEnvPath();
String[] auPaths = auPath.split(CoreConstants.SEPARATOR);
String[] nodePaths = fileName.split(CoreConstants.SEPARATOR);
if (auPaths.length == nodePaths.length) {
for (int i = 0; i < auPaths.length; i++) {
if (!auPaths[i].equals(nodePaths[i])) {
return false;
}
}
return fileNode.isDirectory();
} else {
int len = Math.min(auPaths.length, nodePaths.length);
for (int i = 0; i < len; i++) {
if (!auPaths[i].equals(nodePaths[i])) {
return false;
}
}
return true;
}
}
private FileNode[] listFileNodes(String filePath) {
FileNode[] fileNodes = null;

51
designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/ExpandMutableTreeNode.java

@ -1,29 +1,46 @@
package com.fr.design.gui.itree.refreshabletree;
import com.fr.design.utils.gui.GUICoreUtils;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import com.fr.design.utils.gui.GUICoreUtils;
/**
* Enhanced, expand state and get treepath from node.
*/
public class ExpandMutableTreeNode extends DefaultMutableTreeNode {
private boolean isExpanded = false; //the expend state
//默认显示:“正在加载”,如需要显示tree,则传入相应userobject
/**
* the expend state
*/
private boolean isExpanded = false;
private boolean hasFullAuthority = true;
/**
* 默认显示:正在加载如需要显示tree则传入相应userobject
*/
public ExpandMutableTreeNode() {
this(RefreshableJTree.PENDING);
this(RefreshableJTree.PENDING);
}
public ExpandMutableTreeNode(Object userObject) {
this(userObject, false);
}
public ExpandMutableTreeNode(Object userObject, boolean isExpanded) {
super(userObject);
this.setExpanded(isExpanded);
super(userObject);
this.setExpanded(isExpanded);
}
public boolean hasFullAuthority() {
return hasFullAuthority;
}
public void setFullAuthority(boolean hasFullAuthority) {
this.hasFullAuthority = hasFullAuthority;
}
public boolean isExpanded() {
return this.isExpanded;
}
@ -36,12 +53,12 @@ public class ExpandMutableTreeNode extends DefaultMutableTreeNode {
* 展开所有Expanded为true的TreeNode
*/
public void expandCurrentTreeNode(JTree tree) {
if (this.isExpanded) {
tree.expandPath(GUICoreUtils.getTreePath(this));
if (this.isExpanded) {
tree.expandPath(GUICoreUtils.getTreePath(this));
this.setExpanded(true);
this.expandSubTreeNodes(tree);
}
}
}
/**
@ -69,10 +86,10 @@ public class ExpandMutableTreeNode extends DefaultMutableTreeNode {
}
}
}
public void addChildTreeNodes(ExpandMutableTreeNode[] newChildNodes) {
for (int i = 0; i < newChildNodes.length; i ++) {
this.add(newChildNodes[i]);
}
for (int i = 0; i < newChildNodes.length; i++) {
this.add(newChildNodes[i]);
}
}
}

80
designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/RefreshableJTree.java

@ -4,16 +4,28 @@ import com.fr.design.constants.UIConstants;
import com.fr.design.gui.itooltip.UIToolTip;
import com.fr.design.gui.itree.checkboxtree.CheckBoxTree;
import com.fr.general.ComparatorUtils;
import com.fr.general.Inter;
import com.fr.general.NameObject;
import com.fr.locale.InterProviderFactory;
import com.fr.stable.StringUtils;
import javax.swing.*;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JToolTip;
import javax.swing.SwingWorker;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.*;
import java.awt.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
public abstract class RefreshableJTree extends CheckBoxTree {
@ -24,16 +36,19 @@ public abstract class RefreshableJTree extends CheckBoxTree {
@Override
public String toString() {
return Inter.getLocText("Loading") + "...";
return InterProviderFactory.getProvider().getLocText("Loading") + "...";
}
};
public RefreshableJTree() {
this(null);
}
@Override
public boolean isCheckBoxVisible(TreePath path) {
return false;
}
public RefreshableJTree(Object rootObj) {
super(new DefaultTreeModel(new ExpandMutableTreeNode(rootObj)));
DefaultTreeModel model = (DefaultTreeModel) getModel();
@ -101,8 +116,7 @@ public abstract class RefreshableJTree extends CheckBoxTree {
treeNode.remove(0);
}
treeModel.nodeStructureChanged(treeNode);
long usedTime = System.currentTimeMillis() - startTime;
return usedTime;
return System.currentTimeMillis() - startTime;
}
@Override
@ -118,15 +132,15 @@ public abstract class RefreshableJTree extends CheckBoxTree {
};
/**
* @return
* @return is template showing
*/
public boolean isTemplateShowing() {
return ((ExpandMutableTreeNode) this.getModel().getRoot()).getChildCount() == 0 ? false : true;
return ((ExpandMutableTreeNode) this.getModel().getRoot()).getChildCount() != 0;
}
/*
* 刷新
*/
* 刷新
*/
public void refresh() {
refresh((ExpandMutableTreeNode) this.getModel().getRoot(), StringUtils.EMPTY);
}
@ -136,8 +150,8 @@ public abstract class RefreshableJTree extends CheckBoxTree {
}
/*
* 刷新expandRoot节点下所有已打开的节点的UserObject,并打开isExpanded为true的TreeNode
*/
* 刷新expandRoot节点下所有已打开的节点的UserObject,并打开isExpanded为true的TreeNode
*/
private void refresh(ExpandMutableTreeNode expandRoot, String childName) {
if (expandRoot == null) {
return;
@ -152,8 +166,8 @@ public abstract class RefreshableJTree extends CheckBoxTree {
}
/*
* 刷新eTreeNode下面所有的已完成过取数的非叶子节点的子叶内容UserObject
*/
* 刷新eTreeNode下面所有的已完成过取数的非叶子节点的子叶内容UserObject
*/
protected void refreshTreeNode(ExpandMutableTreeNode eTreeNode, String childName) {
// 如果eTreeNode是未取数状态,不用expand
if (interceptRefresh(eTreeNode)) {
@ -161,12 +175,12 @@ public abstract class RefreshableJTree extends CheckBoxTree {
}
// 刷新当前eTreeNode下面的子节点的UserObject的数组
ExpandMutableTreeNode[] new_nodes = loadChildTreeNodes(eTreeNode);
ExpandMutableTreeNode[] newNodes = loadChildTreeNodes(eTreeNode);
/*
* 保存下当前eTreeNode下的ChildTreeNode于childTreeNodeList 移除所有ChildTreeNode
* 根据childUserObjects与childTreeNodeList的比对,重新构建eTreeNode
*/
* 保存下当前eTreeNode下的ChildTreeNode于childTreeNodeList 移除所有ChildTreeNode
* 根据childUserObjects与childTreeNodeList的比对,重新构建eTreeNode
*/
java.util.List<DefaultMutableTreeNode> childTreeNodeList = new java.util.ArrayList<DefaultMutableTreeNode>();
for (int i = 0, len = eTreeNode.getChildCount(); i < len; i++) {
if (eTreeNode.getChildAt(i) instanceof ExpandMutableTreeNode) {
@ -178,29 +192,29 @@ public abstract class RefreshableJTree extends CheckBoxTree {
eTreeNode.removeAllChildren();
for (int ci = 0; ci < new_nodes.length; ci++) {
Object cUserObject = new_nodes[ci].getUserObject();
for (int ci = 0; ci < newNodes.length; ci++) {
Object cUserObject = newNodes[ci].getUserObject();
for (int ni = 0, nlen = childTreeNodeList.size(); ni < nlen; ni++) {
for (int ni = 0, len = childTreeNodeList.size(); ni < len; ni++) {
ExpandMutableTreeNode cTreeNode = (ExpandMutableTreeNode) childTreeNodeList.get(ni);
if (ComparatorUtils.equals(cTreeNode.getUserObject(), cUserObject)) {
new_nodes[ci].setExpanded(cTreeNode.isExpanded());
newNodes[ci].setExpanded(cTreeNode.isExpanded());
break;
}
}
eTreeNode.add(new_nodes[ci]);
eTreeNode.add(newNodes[ci]);
}
}
/*
* 判断eTreeNode是否需要Refresh,可提前中止,返回true则表示提前中止,不需要Refresh
*/
* 判断eTreeNode是否需要Refresh,可提前中止,返回true则表示提前中止,不需要Refresh
*/
protected abstract boolean interceptRefresh(ExpandMutableTreeNode eTreeNode);
/*
* 得到treeNode的子节点ExpandMutableTreeNode的数组
*/
* 得到treeNode的子节点ExpandMutableTreeNode的数组
*/
protected abstract ExpandMutableTreeNode[] loadChildTreeNodes(ExpandMutableTreeNode treeNode);
public NameObject getSelectedNameObject() {
@ -223,6 +237,7 @@ public abstract class RefreshableJTree extends CheckBoxTree {
return null;
}
@Override
public String getToolTipText(MouseEvent event) {
String tip = null;
icon = new ImageIcon();
@ -238,7 +253,7 @@ public abstract class RefreshableJTree extends CheckBoxTree {
Object lastPath = path.getLastPathComponent();
if (lastPath instanceof TreeNode) {
TreeNode treeNode = (TreeNode) lastPath;
while (treeNode.getParent() instanceof TreeNode) {
while (treeNode.getParent() != null) {
i++;
treeNode = treeNode.getParent();
}
@ -260,6 +275,7 @@ public abstract class RefreshableJTree extends CheckBoxTree {
return tip;
}
@Override
public Point getToolTipLocation(MouseEvent event) {
if (event != null) {
Point p = event.getPoint();
@ -268,12 +284,16 @@ public abstract class RefreshableJTree extends CheckBoxTree {
if (selRow != -1 && r != null) {
TreePath path = getPathForRow(selRow);
Rectangle pathBounds = getPathBounds(path);
return new Point(pathBounds.x - 2, pathBounds.y - 1);
if (pathBounds != null) {
return new Point(pathBounds.x - 2, pathBounds.y - 1);
}
return null;
}
}
return null;
}
@Override
public JToolTip createToolTip() {
UIToolTip tip = new UIToolTip(icon);
tip.setComponent(this);

4
designer-base/src/main/java/com/fr/design/remote/ui/AuthorityEditorPane.java

@ -12,10 +12,10 @@ import com.fr.general.Inter;
import com.fr.report.DesignAuthority;
import com.fr.stable.CoreConstants;
import javax.swing.*;
import javax.swing.BorderFactory;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.List;

126
designer-base/src/main/java/com/fr/design/remote/ui/UserManagerPane.java

@ -13,7 +13,7 @@ import com.fr.design.remote.ui.list.AddedMemberListCellRender;
import com.fr.design.remote.ui.list.AddingMemberList;
import com.fr.design.remote.ui.list.AddingMemberListCellRender;
import com.fr.design.remote.ui.list.MemberListSelectedChangeListener;
import com.fr.general.Inter;
import com.fr.locale.InterProviderFactory;
import com.fr.stable.StringUtils;
import com.fr.third.guava.collect.ImmutableList;
import com.fr.workspace.WorkContext;
@ -23,9 +23,12 @@ import com.fr.workspace.server.authority.decision.DecisionOperator;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JPanel;
import javax.swing.JViewport;
import javax.swing.ListSelectionModel;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
@ -33,10 +36,15 @@ import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@ -45,10 +53,15 @@ import java.util.List;
*/
public class UserManagerPane extends BasicPane {
/**
* 每页个数
*/
private final int DEFAULT_NUM_EACH_PAGE = 50;
/**
* 获取的决策平台成员
*/
private List<RemoteDesignMember> addingMembers = new ArrayList<>();
private final List<RemoteDesignMember> addingMembers = new ArrayList<>();
/**
* 添加到设计的决策平台成员
*/
@ -73,7 +86,7 @@ public class UserManagerPane extends BasicPane {
private ActionListener keyButtonActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
searchAddingMembers(keyField.getText());
searchAddingMembers(keyWord);
}
};
@ -84,9 +97,9 @@ public class UserManagerPane extends BasicPane {
@Override
public void keyReleased(KeyEvent e) {
// 判断按下的键是否是回车键
// todo 对话框回车键绑定的是对话框的确定按钮
// 对话框回车键绑定的是对话框的确定按钮,因此按确定没有办法搜索
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
searchAddingMembers(keyField.getText());
searchAddingMembers(keyWord);
}
}
};
@ -125,7 +138,7 @@ public class UserManagerPane extends BasicPane {
sync2AddedMembersFormAdded();
// 不需要重复更新右侧列表显示 但是更新一下计数显示
countLabel.setText(
Inter.getLocText("Fine-Designer_Remote_Design_Selected_Member_Count",
InterProviderFactory.getProvider().getLocText("Fine-Designer_Remote_Design_Selected_Member_Count",
String.valueOf(addedMembers.size())
)
);
@ -134,9 +147,47 @@ public class UserManagerPane extends BasicPane {
}
};
/**
* 已经添加的成员列表
*/
private AddedMemberList addedList;
/**
* 待添加的成员列表
*/
private AddingMemberList addingList;
/**
* 搜索关键字
*/
private String keyWord;
/**
* 搜索关键词变更监听
*/
private DocumentListener documentListener = new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
keyWord = keyField.getText();
}
@Override
public void removeUpdate(DocumentEvent e) {
keyWord = keyField.getText();
}
@Override
public void changedUpdate(DocumentEvent e) {
keyWord = keyField.getText();
}
};
/**
* 当前分页计数
*/
private int pageNum = 1;
public UserManagerPane() {
this.setBorder(BorderFactory.createEmptyBorder());
@ -155,7 +206,7 @@ public class UserManagerPane extends BasicPane {
@Override
protected String title4PopupWindow() {
return Inter.getLocText("Fine-Designer_Remote_Design_Add_Member");
return InterProviderFactory.getProvider().getLocText("Fine-Designer_Remote_Design_Add_Member");
}
private JPanel createLeftPanel() {
@ -165,7 +216,7 @@ public class UserManagerPane extends BasicPane {
BorderFactory.createCompoundBorder(
new EmptyBorder(6, 0, 0, 0),
UITitledBorder.createBorderWithTitle(
Inter.getLocText("Fine-Designer_Remote_Design_Decision_Member")
InterProviderFactory.getProvider().getLocText("Fine-Designer_Remote_Design_Decision_Member")
)
)
);
@ -176,7 +227,8 @@ public class UserManagerPane extends BasicPane {
keyField.setPreferredSize(new Dimension(250, 20));
keyField.requestFocus();
keyField.addKeyListener(keyFieldKeyListener);
keyButton.setText(Inter.getLocText("Fine-Designer_Remote_Design_Search"));
keyField.getDocument().addDocumentListener(documentListener);
keyButton.setText(InterProviderFactory.getProvider().getLocText("Fine-Designer_Remote_Design_Search"));
keyButton.addActionListener(keyButtonActionListener);
searchPanel.add(keyField);
searchPanel.add(keyButton);
@ -189,7 +241,25 @@ public class UserManagerPane extends BasicPane {
resetMembers();
addToMemberList();
searchAddingMembers(StringUtils.EMPTY);
UIScrollPane listPane = new UIScrollPane(addingList);
final UIScrollPane listPane = new UIScrollPane(addingList);
listPane.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
JViewport vp = listPane.getViewport();
if (vp.getView().getHeight() <= vp.getHeight() + vp.getViewPosition().y) {
loadMoreAddingMembers(keyWord, DEFAULT_NUM_EACH_PAGE);
}
}
});
listPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
JViewport vp = listPane.getViewport();
if (vp.getView().getHeight() <= vp.getHeight() + vp.getViewPosition().y && e.getValueIsAdjusting()) {
loadMoreAddingMembers(keyWord, DEFAULT_NUM_EACH_PAGE);
}
}
});
listPane.setBorder(BorderFactory.createEmptyBorder());
content.add(searchPanel, BorderLayout.NORTH);
@ -205,14 +275,14 @@ public class UserManagerPane extends BasicPane {
BorderFactory.createCompoundBorder(
new EmptyBorder(6, 0, 0, 0),
UITitledBorder.createBorderWithTitle(
Inter.getLocText("Fine-Designer_Remote_Design_Selected_Member")
InterProviderFactory.getProvider().getLocText("Fine-Designer_Remote_Design_Selected_Member")
)
)
);
// 计数
countLabel.setText(
Inter.getLocText("Fine-Designer_Remote_Design_Selected_Member_Count",
InterProviderFactory.getProvider().getLocText("Fine-Designer_Remote_Design_Selected_Member_Count",
String.valueOf(addedMembers.size()))
);
countLabel.setBorder(BorderFactory.createEmptyBorder(7, 12, 8, 0));
@ -258,7 +328,7 @@ public class UserManagerPane extends BasicPane {
addedList.revalidate();
addedList.repaint();
countLabel.setText(
Inter.getLocText("Fine-Designer_Remote_Design_Selected_Member_Count",
InterProviderFactory.getProvider().getLocText("Fine-Designer_Remote_Design_Selected_Member_Count",
String.valueOf(addedMembers.size())
));
}
@ -280,7 +350,10 @@ public class UserManagerPane extends BasicPane {
protected List<RemoteDesignMember> doInBackground() {
addingMembers.clear();
String username = WorkContext.getConnector().currentUser();
addingMembers.addAll(WorkContext.getCurrent().get(DecisionOperator.class).getMembers(username, keyword));
synchronized (addingMembers) {
addingMembers.addAll(WorkContext.getCurrent().get(DecisionOperator.class).getMembers(username, keyword));
pageNum = 1;
}
return addingMembers;
}
@ -292,6 +365,31 @@ public class UserManagerPane extends BasicPane {
getMemberWorker.execute();
}
private void loadMoreAddingMembers(final String keyword, final int count) {
final SwingWorker loadMoreWorker = new SwingWorker<List<RemoteDesignMember>, Void>() {
@Override
protected List<RemoteDesignMember> doInBackground() {
String username = WorkContext.getConnector().currentUser();
synchronized (addingMembers) {
Collection<RemoteDesignMember> more =
WorkContext.getCurrent().get(DecisionOperator.class).getMembers(username, keyword, pageNum + 1, count);
if (!more.isEmpty()) {
pageNum += 1;
}
addingMembers.addAll(more);
}
return addingMembers;
}
@Override
protected void done() {
addToMemberList();
}
};
loadMoreWorker.execute();
}
private void sync2AddedMembersFromAdding() {
RemoteDesignMember[] members = new RemoteDesignMember[addingListModel.getSize()];

16
designer-base/src/main/java/com/fr/design/remote/ui/list/AddedMemberList.java

@ -3,8 +3,6 @@ package com.fr.design.remote.ui.list;
import com.fr.workspace.server.authority.RemoteDesignMember;
import javax.swing.DefaultListModel;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.Vector;
public class AddedMemberList extends MemberList {
@ -25,20 +23,6 @@ public class AddedMemberList extends MemberList {
super(listData);
}
@Override
protected boolean shouldDisplaySelected(MouseEvent e) {
Point point = e.getPoint();
int rX = point.x;
int rY = point.y;
int index = this.getSelectedIndex();
int x = 280;
int y = 25 * index;
int width = 20;
int height = 25;
return x <= rX && rX <= x + width && y <= rY && rY <= y + height;
}
@Override
protected void displaySelected() {
RemoteDesignMember member = getSelectedValue();

2
designer-base/src/main/java/com/fr/design/remote/ui/list/AddedMemberListCellRender.java

@ -24,7 +24,7 @@ public class AddedMemberListCellRender extends JPanel implements ListCellRendere
label = new UILabel();
label.setIcon(BaseUtils.readIcon("com/fr/design/remote/images/icon_Member_normal@1x.png"));
label.setPreferredSize(new Dimension(270, 20));
label.setPreferredSize(new Dimension(260, 20));
this.setPreferredSize(new Dimension(this.getPreferredSize().width, 25));
this.add(label);

15
designer-base/src/main/java/com/fr/design/remote/ui/list/AddingMemberList.java

@ -3,8 +3,6 @@ package com.fr.design.remote.ui.list;
import com.fr.workspace.server.authority.RemoteDesignMember;
import javax.swing.DefaultListModel;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.Vector;
public class AddingMemberList extends MemberList {
@ -36,19 +34,6 @@ public class AddingMemberList extends MemberList {
repaint();
fireSelectedChange();
}
@Override
protected boolean shouldDisplaySelected(MouseEvent e) {
Point point = e.getPoint();
int rX = point.x;
int rY = point.y;
int index = this.getSelectedIndex();
int x = 280;
int y = 25 * index;
int width = 25;
int height = 25;
return x <= rX && rX <= x + width && y <= rY && rY <= y + height;
}
}

13
designer-base/src/main/java/com/fr/design/remote/ui/list/AddingMemberListCellRender.java

@ -24,7 +24,7 @@ public class AddingMemberListCellRender extends JPanel implements ListCellRender
this.setLayout(new FlowLayout(FlowLayout.LEFT));
label = new UILabel();
label.setPreferredSize(new Dimension(270, 20));
label.setPreferredSize(new Dimension(260, 20));
this.setPreferredSize(new Dimension(this.getPreferredSize().width, 25));
label.setIcon(BaseUtils.readIcon("com/fr/design/remote/images/icon_Member_normal@1x.png"));
@ -39,8 +39,15 @@ public class AddingMemberListCellRender extends JPanel implements ListCellRender
@Override
public Component getListCellRendererComponent(JList list, RemoteDesignMember member, int index, boolean isSelected, boolean cellHasFocus) {
this.setLabelText(member.getRealName() + "(" + member.getUsername() + ")");
check.setSelected(member.isSelected());
if (member.equals(RemoteDesignMember.DEFAULT_MEMBER)) {
this.setLabelText(member.getUsername());
check.setVisible(false);
} else {
this.setLabelText(member.getRealName() + "(" + member.getUsername() + ")");
check.setVisible(true);
check.setSelected(member.isSelected());
}
return this;
}

19
designer-base/src/main/java/com/fr/design/remote/ui/list/MemberList.java

@ -7,6 +7,7 @@ import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.ListSelectionModel;
import java.awt.Color;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
@ -14,6 +15,12 @@ import java.awt.event.MouseEvent;
import java.util.Vector;
public abstract class MemberList extends JList<RemoteDesignMember> {
static final int TRIGGER_AREA_X = 270;
static final int TRIGGER_AREA_Y_EACH = 25;
static final int TRIGGER_AREA_WIDTH = 25;
static final int TRIGGER_AREA_HEIGHT = 25;
public MemberList(DefaultListModel<RemoteDesignMember> dataModel) {
super(dataModel);
@ -79,7 +86,13 @@ public abstract class MemberList extends JList<RemoteDesignMember> {
abstract protected void displaySelected();
abstract protected boolean shouldDisplaySelected(MouseEvent e);
protected boolean shouldDisplaySelected(MouseEvent e) {
Point point = e.getPoint();
int rX = point.x;
int rY = point.y;
int index = this.getSelectedIndex();
int x = TRIGGER_AREA_X;
int y = TRIGGER_AREA_Y_EACH * index;
return x <= rX && rX <= x + TRIGGER_AREA_WIDTH && y <= rY && rY <= y + TRIGGER_AREA_HEIGHT;
}
}

BIN
designer-base/src/main/resources/com/fr/design/images/gui/filetree_folder_half_authority_normal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

5
designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java

@ -183,7 +183,10 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane<Chart> {
private void checkZoomEnabled() {
if (zoomWidget != null && axisRotation != null) {
zoomWidget.setSelectedIndex(1);
if (axisRotation.getSelectedIndex() == 0) {
//只有开启坐标轴翻转,才需要将缩放控件强制关闭。
zoomWidget.setSelectedIndex(1);
}
checkZoomPane();
zoomWidget.setEnabled(axisRotation.getSelectedIndex() == 1);
}

Loading…
Cancel
Save