You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1110 lines
42 KiB
1110 lines
42 KiB
package com.fr.design.mainframe; |
|
|
|
import com.fr.base.BaseUtils; |
|
import com.fr.base.vcs.DesignerMode; |
|
import com.fr.design.DesignerEnvManager; |
|
import com.fr.design.constants.UIConstants; |
|
import com.fr.design.gui.ibutton.UIButton; |
|
import com.fr.design.gui.ibutton.UIButtonUI; |
|
import com.fr.design.gui.icontainer.UIEastResizableContainer; |
|
import com.fr.design.gui.ilable.UILabel; |
|
import com.fr.design.layout.VerticalFlowLayout; |
|
import com.fr.design.utils.gui.GUICoreUtils; |
|
import com.fr.design.utils.gui.GUIPaintUtils; |
|
import com.fr.general.FRFont; |
|
import com.fr.general.Inter; |
|
import com.fr.stable.StringUtils; |
|
|
|
import javax.swing.*; |
|
import javax.swing.border.EmptyBorder; |
|
import java.awt.*; |
|
import java.awt.event.ActionEvent; |
|
import java.awt.event.ActionListener; |
|
import java.awt.event.MouseAdapter; |
|
import java.awt.event.MouseEvent; |
|
import java.awt.event.MouseListener; |
|
import java.awt.event.MouseMotionListener; |
|
import java.util.HashSet; |
|
import java.util.LinkedHashMap; |
|
import java.util.Map; |
|
import java.util.Set; |
|
|
|
public class EastRegionContainerPane extends UIEastResizableContainer { |
|
private static volatile EastRegionContainerPane THIS; |
|
private Map<String, PropertyItem> propertyItemMap; |
|
private CardLayout propertyCard; |
|
private JPanel leftPane; |
|
private JPanel rightPane; |
|
private FixedPopupPane currentPopupPane; |
|
private static final int CONTAINER_WIDTH = 286; |
|
private static final int TAB_WIDTH = 38; |
|
private static final int TAB_BUTTON_WIDTH = 32; |
|
private static final int TAB_BUTTON_HEIGHT = 28; |
|
private static final int CONTENT_WIDTH = CONTAINER_WIDTH - TAB_WIDTH; |
|
private static final int POPUP_TOOLPANE_HEIGHT = 27; |
|
private static final int ARROW_RANGE_START = CONTENT_WIDTH - 30; |
|
// 弹出对话框高度 |
|
private static final int POPUP_MIN_HEIGHT = 145; |
|
private static final int POPUP_DEFAULT_HEIGHT = 356; |
|
public static final String KEY_CELL_ELEMENT = "cellElement"; |
|
public static final String KEY_CELL_ATTR = "cellAttr"; |
|
public static final String KEY_FLOAT_ELEMENT = "floatElement"; |
|
public static final String KEY_WIDGET_SETTINGS = "widgetSettings"; |
|
public static final String KEY_CONDITION_ATTR = "conditionAttr"; |
|
public static final String KEY_HYPERLINK = "hyperlink"; |
|
public static final String KEY_WIDGET_LIB = "widgetLib"; |
|
public static final String KEY_AUTHORITY_EDITION = "authorityEdition"; |
|
public static final String KEY_CONFIGURED_ROLES = "editedRoles"; |
|
public static final String DEFAULT_PANE = "defaultPane"; |
|
public static final String DEFAULT_AUTHORITY_PANE = "defaultAuthorityPane"; |
|
|
|
private JPanel defaultPane; // "无可用配置项"面板 |
|
private JPanel defaultAuthorityPane; // "该元素不支持权限编辑" |
|
private PropertyItem selectedItem; // 当前被选中的属性配置项 |
|
|
|
public enum PropertyMode { |
|
REPORT, // 报表 |
|
REPORT_PARA, // 报表参数面板 |
|
REPORT_FLOAT, // 报表悬浮元素 |
|
FORM, // 表单 |
|
FORM_REPORT, // 表单报表块 |
|
POLY, // 聚合报表 |
|
POLY_REPORT, // 聚合报表-报表块 |
|
POLY_CHART, // 聚合报表-图表块 |
|
AUTHORITY_EDITION, // 权限编辑 |
|
AUTHORITY_EDITION_DISABLED // 权限编辑 |
|
} |
|
private PropertyMode currentMode; // 当前模式(根据不同模式,显示不同的可用面板) |
|
|
|
|
|
/** |
|
* 得到实例 |
|
* |
|
* @return |
|
*/ |
|
public static EastRegionContainerPane getInstance() { |
|
if (THIS == null) { |
|
synchronized (EastRegionContainerPane.class) { |
|
if (THIS == null) { |
|
THIS = new EastRegionContainerPane(); |
|
THIS.setLastContainerWidth(DesignerEnvManager.getEnvManager().getLastEastRegionContainerWidth()); |
|
} |
|
} |
|
} |
|
return THIS; |
|
} |
|
|
|
private EastRegionContainerPane() { |
|
super(); |
|
initPropertyItemList(); |
|
defaultPane = getDefaultPane(Inter.getLocText("FR-Designer_No_Settings_Available")); |
|
defaultAuthorityPane = getDefaultPane(Inter.getLocText("FR-Designer_Not_Support_Authority_Edit")); |
|
switchMode(PropertyMode.REPORT); |
|
setContainerWidth(CONTAINER_WIDTH); |
|
} |
|
|
|
private void initPropertyItemList() { |
|
propertyItemMap = new LinkedHashMap<>(); // 有序map |
|
// 单元格元素 |
|
PropertyItem cellElement = new PropertyItem(KEY_CELL_ELEMENT, Inter.getLocText("FR-Designer_Cell_Element"), |
|
"cellelement", new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_PARA, PropertyMode.REPORT_FLOAT, PropertyMode.POLY, PropertyMode.POLY_CHART}, |
|
new PropertyMode[]{PropertyMode.REPORT, PropertyMode.FORM_REPORT, PropertyMode.POLY_REPORT}); |
|
// 单元格属性 |
|
PropertyItem cellAttr = new PropertyItem(KEY_CELL_ATTR, Inter.getLocText("FR-Designer_Cell_Attributes"), |
|
"cellattr", new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_PARA, PropertyMode.REPORT_FLOAT, PropertyMode.POLY, PropertyMode.POLY_CHART}, |
|
new PropertyMode[]{PropertyMode.REPORT, PropertyMode.FORM_REPORT, PropertyMode.POLY_REPORT}); |
|
// 悬浮元素 |
|
PropertyItem floatElement = new PropertyItem(KEY_FLOAT_ELEMENT, Inter.getLocText("FR-Designer_Float_Element"), |
|
"floatelement", new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_PARA, PropertyMode.REPORT_FLOAT, PropertyMode.POLY, PropertyMode.POLY_CHART}, |
|
new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_FLOAT, PropertyMode.POLY_REPORT}); |
|
// 控件设置 |
|
PropertyItem widgetSettings = new PropertyItem(KEY_WIDGET_SETTINGS, Inter.getLocText("FR-Designer-Widget_Settings"), |
|
"widgetsettings", new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_PARA, PropertyMode.REPORT_FLOAT, PropertyMode.FORM, PropertyMode.POLY}, |
|
new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_PARA, PropertyMode.FORM, PropertyMode.POLY_REPORT, PropertyMode.POLY_CHART}); |
|
// 条件属性 |
|
PropertyItem conditionAttr = new PropertyItem(KEY_CONDITION_ATTR, Inter.getLocText("FR-Designer_Condition_Attributes"), |
|
"conditionattr", new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_PARA, PropertyMode.REPORT_FLOAT, PropertyMode.POLY, PropertyMode.POLY_CHART}, |
|
new PropertyMode[]{PropertyMode.REPORT, PropertyMode.FORM_REPORT, PropertyMode.POLY_REPORT}); |
|
// 超级链接 |
|
PropertyItem hyperlink = new PropertyItem(KEY_HYPERLINK, Inter.getLocText("FR-Designer_Hyperlink"), |
|
"hyperlink", new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_PARA, PropertyMode.REPORT_FLOAT, PropertyMode.POLY, PropertyMode.POLY_CHART}, |
|
new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_FLOAT, PropertyMode.FORM_REPORT, PropertyMode.POLY_REPORT}); |
|
// 组件库 |
|
PropertyItem widgetLib = new PropertyItem(KEY_WIDGET_LIB, Inter.getLocText("FR-Designer_Widget_Library"), |
|
"widgetlib", new PropertyMode[]{PropertyMode.FORM}, |
|
new PropertyMode[]{PropertyMode.FORM}); |
|
// 权限编辑 |
|
PropertyItem authorityEdition = new PropertyItem(KEY_AUTHORITY_EDITION, Inter.getLocText("FR-Designer_Permissions_Edition"), |
|
"authorityedit", new PropertyMode[]{PropertyMode.AUTHORITY_EDITION_DISABLED}, |
|
new PropertyMode[]{PropertyMode.AUTHORITY_EDITION}); |
|
// 已配置角色 |
|
PropertyItem configuredRoles = new PropertyItem(KEY_CONFIGURED_ROLES, Inter.getLocText("FR-Designer_Configured_Roles"), |
|
"configuredroles", new PropertyMode[]{PropertyMode.AUTHORITY_EDITION_DISABLED}, |
|
new PropertyMode[]{PropertyMode.AUTHORITY_EDITION}); |
|
|
|
propertyItemMap.put(KEY_CELL_ELEMENT, cellElement); |
|
propertyItemMap.put(KEY_CELL_ATTR, cellAttr); |
|
propertyItemMap.put(KEY_FLOAT_ELEMENT, floatElement); |
|
propertyItemMap.put(KEY_WIDGET_SETTINGS, widgetSettings); |
|
propertyItemMap.put(KEY_CONDITION_ATTR, conditionAttr); |
|
propertyItemMap.put(KEY_HYPERLINK, hyperlink); |
|
propertyItemMap.put(KEY_WIDGET_LIB, widgetLib); |
|
propertyItemMap.put(KEY_AUTHORITY_EDITION, authorityEdition); |
|
propertyItemMap.put(KEY_CONFIGURED_ROLES, configuredRoles); |
|
} |
|
|
|
// "无可用配置项"面板 |
|
private JPanel getDefaultPane(String prompt) { |
|
JPanel defaultPane = new JPanel(); |
|
UILabel label = new UILabel(prompt); |
|
label.setHorizontalAlignment(SwingConstants.CENTER); |
|
defaultPane.setLayout(new BorderLayout()); |
|
defaultPane.add(label, BorderLayout.CENTER); |
|
return defaultPane; |
|
} |
|
|
|
public void updateCellElementState(boolean isSelectedOneCell) { |
|
PropertyItem cellElement = propertyItemMap.get(KEY_CELL_ELEMENT); |
|
if (isSelectedOneCell) { |
|
enableCellElementPane(cellElement); |
|
} else { // 如果选中多个单元格,禁用单元格元素 tab |
|
disableCellElementPane(cellElement); |
|
refreshRightPane(); |
|
} |
|
} |
|
|
|
// 禁用单元格元素tab |
|
private void disableCellElementPane(PropertyItem cellElement) { |
|
cellElement.setEnabled(false); |
|
if (cellElement.isPoppedOut()) { |
|
cellElement.popupDialog.showDefaultPane(); |
|
} |
|
} |
|
// 禁用单元格元素tab |
|
private void enableCellElementPane(PropertyItem cellElement) { |
|
cellElement.setEnabled(true); |
|
if (cellElement.isPoppedOut()) { |
|
cellElement.popupDialog.replaceContentPane(cellElement); |
|
} |
|
} |
|
|
|
private void initContentPane() { |
|
initRightPane(); |
|
initLeftPane(); |
|
} |
|
|
|
// 右侧属性面板 |
|
private void initRightPane() { |
|
rightPane = new JPanel(); |
|
propertyCard = new CardLayout(); |
|
rightPane.setBackground(Color.green); |
|
rightPane.setLayout(propertyCard); |
|
for (PropertyItem item : propertyItemMap.values()) { |
|
if (item.isPoppedOut() || !item.isVisible()) { |
|
continue; |
|
} |
|
rightPane.add(item.getName(), item.getPropertyPanel()); |
|
} |
|
rightPane.add(DEFAULT_PANE, defaultPane); |
|
rightPane.add(DEFAULT_AUTHORITY_PANE, defaultAuthorityPane); |
|
|
|
replaceRightPane(rightPane); |
|
refreshRightPane(); |
|
} |
|
|
|
// 左侧按钮面板 |
|
private void initLeftPane() { |
|
leftPane = new JPanel(); |
|
leftPane.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP, 4, 4)); |
|
for (PropertyItem item : propertyItemMap.values()) { |
|
if (item.isPoppedOut() || !item.isVisible()) { |
|
continue; |
|
} |
|
leftPane.add(item.getButton()); |
|
} |
|
|
|
leftPane.setBackground(UIConstants.PROPERTY_PANE_BACKGROUND); |
|
replaceLeftPane(leftPane); |
|
} |
|
|
|
public void switchMode(PropertyMode mode) { |
|
if (currentMode != null && currentMode.equals(mode)) { |
|
return; |
|
} |
|
currentMode = mode; |
|
updateAllPropertyPane(); |
|
} |
|
|
|
/** |
|
* 可通过此方法,判断当前的编辑模式 |
|
* */ |
|
public PropertyMode getCurrentMode() { |
|
return currentMode; |
|
} |
|
|
|
public void updateAllPropertyPane() { |
|
updatePropertyItemMap(); |
|
initContentPane(); |
|
} |
|
|
|
private void updatePropertyItemMap() { |
|
for (PropertyItem item : propertyItemMap.values()) { |
|
item.updateStatus(); |
|
} |
|
} |
|
|
|
// 弹出面板时,更新框架内容 |
|
private void removeItem(PropertyItem propertyItem) { |
|
leftPane.remove(propertyItem.getButton()); |
|
rightPane.remove(propertyItem.getPropertyPanel()); |
|
refreshRightPane(); |
|
refreshContainer(); |
|
} |
|
|
|
@Override |
|
public void onResize() { |
|
if (!isRightPaneVisible()) { |
|
resetPropertyIcons(); |
|
} else { |
|
refreshRightPane(); |
|
} |
|
for (PropertyItem item : propertyItemMap.values()) { |
|
item.onResize(); |
|
} |
|
} |
|
|
|
public EastRegionContainerPane(JPanel leftPane, JPanel rightPane) { |
|
super(leftPane, rightPane); |
|
} |
|
|
|
public void replaceUpPane(JComponent pane) { |
|
replaceCellElementPane(pane); |
|
} |
|
|
|
public void replaceDownPane(JComponent pane) { |
|
replaceCellAttrPane(pane); |
|
} |
|
|
|
public JComponent getUpPane() { |
|
return getCellElementPane(); |
|
} |
|
|
|
public JComponent getDownPane() { |
|
return getCellAttrPane(); |
|
} |
|
|
|
public void replaceCellElementPane(JComponent pane) { |
|
propertyItemMap.get(KEY_CELL_ELEMENT).replaceContentPane(pane); |
|
} |
|
|
|
public JComponent getCellElementPane() { |
|
return propertyItemMap.get(KEY_CELL_ELEMENT).getContentPane(); |
|
} |
|
|
|
public void replaceCellAttrPane(JComponent pane) { |
|
propertyItemMap.get(KEY_CELL_ATTR).replaceContentPane(pane); |
|
} |
|
|
|
public JComponent getCellAttrPane() { |
|
return propertyItemMap.get(KEY_CELL_ATTR).getContentPane(); |
|
} |
|
|
|
public void replaceFloatElementPane(JComponent pane) { |
|
propertyItemMap.get(KEY_FLOAT_ELEMENT).replaceContentPane(pane); |
|
} |
|
|
|
public JComponent getFloatElementPane() { |
|
return propertyItemMap.get(KEY_FLOAT_ELEMENT).getContentPane(); |
|
} |
|
|
|
public void replaceWidgetSettingsPane(JComponent pane) { |
|
propertyItemMap.get(KEY_WIDGET_SETTINGS).replaceContentPane(pane); |
|
} |
|
|
|
public JComponent getWidgetSettingsPane() { |
|
return propertyItemMap.get(KEY_WIDGET_SETTINGS).getContentPane(); |
|
} |
|
|
|
public void replaceConditionAttrPane(JComponent pane) { |
|
propertyItemMap.get(KEY_CONDITION_ATTR).replaceContentPane(pane); |
|
} |
|
|
|
public JComponent getConditionAttrPane() { |
|
return propertyItemMap.get(KEY_CONDITION_ATTR).getContentPane(); |
|
} |
|
|
|
public void replaceHyperlinkPane(JComponent pane) { |
|
propertyItemMap.get(KEY_HYPERLINK).replaceContentPane(pane); |
|
} |
|
|
|
public JComponent getHyperlinkPane() { |
|
return propertyItemMap.get(KEY_HYPERLINK).getContentPane(); |
|
} |
|
|
|
public void replaceWidgetLibPane(JComponent pane) { |
|
propertyItemMap.get(KEY_WIDGET_LIB).replaceContentPane(pane); |
|
} |
|
|
|
public JComponent getWidgetLibPane() { |
|
return propertyItemMap.get(KEY_WIDGET_LIB).getContentPane(); |
|
} |
|
|
|
public void replaceAuthorityEditionPane(JComponent pane) { |
|
propertyItemMap.get(KEY_AUTHORITY_EDITION).replaceContentPane(pane); |
|
} |
|
|
|
public JComponent getAuthorityEditionPane() { |
|
return propertyItemMap.get(KEY_AUTHORITY_EDITION).getContentPane(); |
|
} |
|
|
|
public void replaceConfiguredRolesPane(JComponent pane) { |
|
propertyItemMap.get(KEY_CONFIGURED_ROLES).replaceContentPane(pane); |
|
} |
|
|
|
public JComponent getConfiguredRolesPane() { |
|
return propertyItemMap.get(KEY_CONFIGURED_ROLES).getContentPane(); |
|
} |
|
|
|
public void addParameterPane(JComponent paraPane) { |
|
propertyItemMap.get(KEY_WIDGET_SETTINGS).replaceHeaderPane(paraPane); |
|
} |
|
|
|
public static void main(String[] args){ |
|
JFrame jf = new JFrame("test"); |
|
// jf = new JFrame("test"); |
|
|
|
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
|
|
|
JPanel cc = new JPanel(); |
|
cc.setBackground(Color.WHITE); |
|
// JPanel leftPane = new JPanel(); |
|
// leftPane.setBackground(Color.yellow); |
|
// JPanel rightPane = new JPanel(); |
|
// rightPane.setBackground(Color.green); |
|
// |
|
// JButton b1, b2; |
|
// b1 = new JButton("b1"); |
|
// b2 = new JButton("b2"); |
|
// b1.setPreferredSize(new Dimension(40, 40)); |
|
// b2.setPreferredSize(new Dimension(40, 40)); |
|
// leftPane.add(b1); |
|
// leftPane.add(b2); |
|
// leftPane.setLayout(new BoxLayout(leftPane, BoxLayout.Y_AXIS)); |
|
|
|
JPanel content = (JPanel)jf.getContentPane(); |
|
// content.setLayout(null); |
|
content.add(cc, BorderLayout.CENTER); |
|
content.add(new EastRegionContainerPane(), BorderLayout.EAST); |
|
GUICoreUtils.centerWindow(jf); |
|
jf.setSize(400, 400); |
|
jf.setVisible(true); |
|
} |
|
|
|
public void removeParameterPane() { |
|
propertyItemMap.get(KEY_WIDGET_SETTINGS).removeHeaderPane(); |
|
} |
|
|
|
public void switchTabTo(String tabName) { |
|
PropertyItem propertyItem = propertyItemMap.get(tabName); |
|
if (propertyItem == null) { |
|
return; |
|
} |
|
if (propertyItem.isVisible() && propertyItem.isEnabled() && !propertyItem.isPoppedOut()) { |
|
propertyCard.show(rightPane, tabName); |
|
propertyItem.setTabButtonSelected(); |
|
} |
|
} |
|
|
|
/** |
|
* 刷新右面板 |
|
*/ |
|
public void refreshRightPane() { |
|
// 可继承,就继承 |
|
if (selectedItem != null && selectedItem.isVisible() && selectedItem.isEnabled() && !selectedItem.isPoppedOut()) { |
|
selectedItem.setTabButtonSelected(); |
|
propertyCard.show(rightPane, selectedItem.getName()); |
|
return; |
|
} |
|
|
|
// 不可继承时,选中第一个可用 tab |
|
boolean hasAvailableTab = false; |
|
boolean hasEnabledTab = false; |
|
for (String name : propertyItemMap.keySet()) { |
|
PropertyItem propertyItem = propertyItemMap.get(name); |
|
if (propertyItem.isVisible() && propertyItem.isEnabled()) { |
|
hasEnabledTab = true; |
|
if (!propertyItem.isPoppedOut()) { |
|
propertyCard.show(rightPane, name); // 显示第一个可用tab |
|
propertyItem.setTabButtonSelected(); |
|
hasAvailableTab = true; |
|
break; |
|
} |
|
} |
|
} |
|
// 无可用 tab 时,显示提示文字 |
|
if (!hasAvailableTab) { |
|
resetPropertyIcons(); |
|
if (!hasEnabledTab && DesignerMode.isAuthorityEditing()) { |
|
propertyCard.show(rightPane, DEFAULT_AUTHORITY_PANE); |
|
} else { |
|
propertyCard.show(rightPane, DEFAULT_PANE); |
|
} |
|
} |
|
} |
|
|
|
public void refreshDownPane() { |
|
} |
|
|
|
private void refreshContainer() { |
|
validate(); |
|
repaint(); |
|
revalidate(); |
|
} |
|
|
|
public int getToolPaneY() { |
|
return 0; |
|
} |
|
|
|
private void hideCurrentPopupPane() { |
|
if (currentPopupPane != null && currentPopupPane.isVisible()) { |
|
currentPopupPane.setVisible(false); |
|
} |
|
} |
|
|
|
|
|
private void resetPropertyIcons() { |
|
for (PropertyItem item : propertyItemMap.values()) { |
|
item.resetButtonIcon(); |
|
} |
|
} |
|
|
|
public boolean isConditionAttrPaneEnabled() { |
|
return propertyItemMap.get(KEY_CONDITION_ATTR).isEnabled(); |
|
} |
|
|
|
public boolean isWidgetSettingsPaneEnabled() { |
|
return propertyItemMap.get(KEY_WIDGET_SETTINGS).isEnabled(); |
|
} |
|
|
|
public boolean isCellAttrPaneEnabled() { |
|
return propertyItemMap.get(KEY_CELL_ATTR).isEnabled(); |
|
} |
|
|
|
|
|
class PropertyItem { |
|
private UIButton button; |
|
private String name; // 用于 card 切换 |
|
private String title; // 用于显示 |
|
private JComponent propertyPanel; |
|
private JComponent contentPane; |
|
private JComponent headerPane; // 在contentPane 上方,可以用于显示参数面板 |
|
private Container contentArea; // 包含 headerPane 和 contentPane |
|
private FixedPopupPane popupPane; // 左侧固定弹出框 |
|
private PopupToolPane popupToolPane; // 弹出工具条 |
|
private PopupDialog popupDialog; // 弹出框 |
|
private boolean isPoppedOut = false; // 是否弹出 |
|
private boolean isVisible = true; // 是否可见 |
|
private boolean isEnabled = true; // 是否可用 |
|
private Set<PropertyMode> visibleModes; |
|
private Set<PropertyMode> enableModes; |
|
|
|
// 完整icon路径为 ICON_BASE_DIR + btnIconName + iconSuffix |
|
private static final String ICON_BASE_DIR = "/com/fr/design/images/buttonicon/propertiestab/"; |
|
private static final String ICON_SUFFIX_NORMAL = "_normal.png"; |
|
private static final String ICON_SUFFIX_DISABLED = "_disabled.png"; |
|
private static final String ICON_SUFFIX_SELECTED = "_selected.png"; |
|
private String btnIconName; |
|
private String iconSuffix = ICON_SUFFIX_NORMAL; // normal, diabled, selected, 三者之一 |
|
private final Color selectedBtnBackground = new Color(0xF5F5F7); |
|
private Color originBtnBackground; |
|
|
|
public PropertyItem(String name, String title, String btnIconName, PropertyMode[] visibleModes, PropertyMode[] enableModes) { |
|
this.name = name; |
|
this.title = title; |
|
this.btnIconName = btnIconName; |
|
initButton(); |
|
initPropertyPanel(); |
|
initModes(visibleModes, enableModes); |
|
} |
|
|
|
private void initModes(PropertyMode[] visibleModes, PropertyMode[] enableModes) { |
|
this.enableModes = new HashSet<>(); |
|
this.visibleModes = new HashSet<>(); |
|
for (PropertyMode enableMode : enableModes) { |
|
this.enableModes.add(enableMode); |
|
} |
|
for (PropertyMode visibleMode : visibleModes) { |
|
this.visibleModes.add(visibleMode); |
|
} |
|
this.visibleModes.addAll(this.enableModes); // 可用必可见 |
|
} |
|
|
|
public void updateStatus() { |
|
setEnabled(enableModes.contains(currentMode)); |
|
setVisible(visibleModes.contains(currentMode)); |
|
if (isPoppedOut()) { |
|
if (!isVisible()) { |
|
popToFrame(); |
|
} else if (!isEnabled()) { |
|
popupDialog.showDefaultPane(); |
|
} |
|
} |
|
} |
|
|
|
public void reAddContentArea() { |
|
propertyPanel.add(contentArea, BorderLayout.CENTER); |
|
} |
|
|
|
public boolean isVisible() { |
|
return isVisible; |
|
} |
|
|
|
public void setVisible(boolean isVisible) { |
|
this.isVisible = isVisible; |
|
} |
|
|
|
public boolean isEnabled() { |
|
return isEnabled; |
|
} |
|
|
|
// 选项不可用 |
|
public void setEnabled(boolean isEnabled) { |
|
this.isEnabled = isEnabled; |
|
button.setEnabled(isEnabled); |
|
} |
|
|
|
private void initPropertyPanel() { |
|
propertyPanel = new JPanel(); |
|
propertyPanel.setBackground(Color.pink); |
|
contentPane = generateContentPane(); |
|
popupToolPane = new PopupToolPane(this, PopupToolPane.DOWN_BUTTON); |
|
headerPane = new JPanel(); |
|
headerPane.setPreferredSize(new Dimension(headerPane.getPreferredSize().width, 0)); // 默认隐藏 |
|
contentArea = new JPanel(new BorderLayout()); |
|
contentArea.add(headerPane, BorderLayout.NORTH); |
|
contentArea.add(contentPane, BorderLayout.CENTER); |
|
propertyPanel.setLayout(new BorderLayout()); |
|
propertyPanel.add(popupToolPane, BorderLayout.NORTH); |
|
propertyPanel.add(contentArea, BorderLayout.CENTER); |
|
} |
|
|
|
public boolean isPoppedOut() { |
|
return isPoppedOut; |
|
} |
|
|
|
public JComponent generateContentPane() { |
|
JComponent contentPane = new JPanel(); |
|
UIButton testBtn = new UIButton(name); |
|
testBtn.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
setEnabled(!button.isEnabled()); |
|
} |
|
}); |
|
contentPane.add(testBtn); |
|
return contentPane; |
|
} |
|
|
|
public void replaceContentPane(JComponent pane) { |
|
contentArea.remove(this.contentPane); |
|
contentArea.add(this.contentPane = pane); |
|
if (popupDialog != null && isPoppedOut) { |
|
popupDialog.replaceContentPane(this); |
|
} |
|
if (popupPane != null && popupPane.isVisible()) { |
|
popupPane.replaceContentPane(contentArea); |
|
} |
|
|
|
refreshContainer(); |
|
} |
|
|
|
public JComponent getContentPane() { |
|
return contentPane; |
|
} |
|
|
|
public Container getContentArea() { |
|
return contentArea; |
|
} |
|
|
|
public void replaceHeaderPane(JComponent pane) { |
|
contentArea.remove(headerPane); |
|
headerPane = pane; |
|
contentArea.add(headerPane, BorderLayout.NORTH); |
|
|
|
refreshContainer(); |
|
} |
|
|
|
public void removeHeaderPane() { |
|
contentArea.remove(headerPane); |
|
refreshContainer(); |
|
} |
|
|
|
public JComponent getHeaderPane() { |
|
return headerPane; |
|
} |
|
|
|
public void onResize() { |
|
if (isRightPaneVisible()) { |
|
hideCurrentPopupPane(); |
|
replaceContentPane(contentPane); |
|
} else if(popupPane != null && popupPane.isVisible()) { |
|
popupPane.replaceContentPane(contentArea); |
|
} |
|
} |
|
|
|
private String getBtnIconUrl() { |
|
return ICON_BASE_DIR + btnIconName + iconSuffix; |
|
} |
|
|
|
public void resetButtonIcon() { |
|
if (iconSuffix.equals(ICON_SUFFIX_SELECTED)) { |
|
iconSuffix = ICON_SUFFIX_NORMAL; |
|
button.setIcon(BaseUtils.readIcon(getBtnIconUrl())); |
|
button.setBackground(originBtnBackground); |
|
button.setOpaque(false); |
|
} |
|
} |
|
|
|
public void setTabButtonSelected() { |
|
resetPropertyIcons(); |
|
iconSuffix = ICON_SUFFIX_SELECTED; |
|
button.setIcon(BaseUtils.readIcon(getBtnIconUrl())); |
|
button.setBackground(selectedBtnBackground); |
|
button.setOpaque(true); |
|
selectedItem = this; |
|
} |
|
|
|
private boolean isTabButtonSelected() { |
|
return button.getBackground() == selectedBtnBackground; |
|
} |
|
|
|
private void initButton() { |
|
button = new UIButton(BaseUtils.readIcon(getBtnIconUrl())) { |
|
public Dimension getPreferredSize() { |
|
return new Dimension(TAB_BUTTON_WIDTH, TAB_BUTTON_HEIGHT); |
|
} |
|
@Override |
|
public void paintComponent(Graphics g) { |
|
super.paintComponent(g); |
|
} |
|
}; |
|
button.set4LargeToolbarButton(); |
|
button.setUI(new UIButtonUI() { |
|
@Override |
|
protected void doExtraPainting(UIButton b, Graphics2D g2d, int w, int h, String selectedRoles) { |
|
if (isPressed(b) && b.isPressedPainted()) { |
|
Color pressColor = isTabButtonSelected() ? UIConstants.TAB_BUTTON_PRESS_SELECTED : UIConstants.TAB_BUTTON_PRESS; |
|
GUIPaintUtils.fillPressed(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), pressColor); |
|
} else if (isRollOver(b)) { |
|
Color hoverColor = isTabButtonSelected() ? UIConstants.TAB_BUTTON_HOVER_SELECTED : UIConstants.TAB_BUTTON_HOVER; |
|
GUIPaintUtils.fillRollOver(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted(), hoverColor); |
|
} else if (b.isNormalPainted()) { |
|
GUIPaintUtils.fillNormal(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted()); |
|
} |
|
} |
|
}); |
|
originBtnBackground = button.getBackground(); |
|
button.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
if (isRightPaneVisible()) { |
|
propertyCard.show(rightPane, name); |
|
} else { |
|
popupFixedPane(); |
|
} |
|
setTabButtonSelected(); |
|
} |
|
}); |
|
button.setToolTipText(title); |
|
} |
|
|
|
public UIButton getButton() { |
|
return button; |
|
} |
|
|
|
public String getName() { |
|
return name; |
|
} |
|
|
|
public String getTitle() { |
|
return title; |
|
} |
|
|
|
public JComponent getPropertyPanel() { |
|
return propertyPanel; |
|
} |
|
|
|
// 固定弹窗 |
|
public void popupFixedPane() { |
|
if (popupPane == null) { |
|
popupPane = new FixedPopupPane(this); |
|
} |
|
if (popupPane.isVisible()) { |
|
popupPane.setVisible(false); |
|
} else { |
|
hideCurrentPopupPane(); |
|
currentPopupPane = popupPane; |
|
GUICoreUtils.showPopupMenu(popupPane, button, -popupPane.getPreferredSize().width, 0); |
|
} |
|
} |
|
|
|
// 弹出对话框 |
|
public void popupDialog() { |
|
if (isPoppedOut) { |
|
return; |
|
} |
|
isPoppedOut = true; |
|
if (popupDialog == null) { |
|
popupDialog = new PopupDialog(this); |
|
} else { |
|
popupDialog.replaceContentPane(this); |
|
popupDialog.adjustLocation(); |
|
popupDialog.setVisible(true); |
|
} |
|
removeItem(this); |
|
} |
|
|
|
public void popToFrame() { |
|
if (isPoppedOut) { |
|
isPoppedOut = false; |
|
popupDialog.setVisible(false); |
|
reAddContentArea(); |
|
initContentPane(); |
|
onResize(); |
|
if (isEnabled()) { |
|
propertyCard.show(rightPane, getName()); |
|
setTabButtonSelected(); |
|
} |
|
refreshContainer(); |
|
} |
|
} |
|
} |
|
|
|
private class FixedPopupPane extends JPopupMenu { |
|
private Container contentPane; |
|
private PropertyItem propertyItem; |
|
|
|
FixedPopupPane(PropertyItem propertyItem) { |
|
this.propertyItem = propertyItem; |
|
contentPane = propertyItem.getContentArea(); |
|
this.setLayout(new BorderLayout()); |
|
this.add(new PopupToolPane(propertyItem), BorderLayout.NORTH); |
|
this.add(contentPane, BorderLayout.CENTER); |
|
this.setOpaque(false); |
|
setPreferredSize(new Dimension(CONTAINER_WIDTH - TAB_WIDTH, POPUP_DEFAULT_HEIGHT)); |
|
} |
|
|
|
@Override |
|
public void setVisible(boolean visible) { |
|
super.setVisible(visible); |
|
if (visible == true) { |
|
replaceContentPane(propertyItem.getContentArea()); |
|
} else { |
|
propertyItem.reAddContentArea(); |
|
} |
|
} |
|
|
|
public void menuSelectionChanged(boolean isIncluded) { |
|
} |
|
|
|
public Container getContentPane() { |
|
return contentPane; |
|
} |
|
|
|
public void replaceContentPane(Container pane) { |
|
this.remove(this.contentPane); |
|
this.add(this.contentPane = pane); |
|
refreshContainer(); |
|
} |
|
|
|
private void refreshContainer() { |
|
validate(); |
|
repaint(); |
|
revalidate(); |
|
} |
|
} |
|
|
|
// 弹出属性面板的工具条 |
|
private class PopupToolPane extends JPanel { |
|
private String title; |
|
private PropertyItem propertyItem; |
|
private String buttonType; |
|
private JDialog parentDialog; // 如果不在对话框中,值为null |
|
private Color originColor; // 初始背景 |
|
private JPanel contentPane; |
|
private boolean isMovable = false; |
|
private Point mouseDownCompCoords; // 存储按下左键的位置,移动对话框时会用到 |
|
|
|
private static final int MIN_X = -150; |
|
private static final int MAX_X_SHIFT = 50; |
|
private static final int MAX_Y_SHIFT = 50; |
|
|
|
private static final String NO_BUTTON = "NoButton"; |
|
private static final String UP_BUTTON = "UpButton"; |
|
private static final String DOWN_BUTTON = "DownButton"; |
|
|
|
private MouseListener mouseListener = new MouseAdapter() { |
|
@Override |
|
public void mouseExited(MouseEvent e) { |
|
setCursor(Cursor.getDefaultCursor()); |
|
if (mouseDownCompCoords == null) { |
|
contentPane.setBackground(originColor); |
|
} |
|
repaint(); |
|
} |
|
@Override |
|
public void mouseClicked(MouseEvent e) { |
|
if (e.getX() >= ARROW_RANGE_START) { |
|
onPop(); |
|
} |
|
} |
|
@Override |
|
public void mouseReleased(MouseEvent e) { |
|
mouseDownCompCoords = null; |
|
if (!getBounds().contains(e.getPoint())) { |
|
contentPane.setBackground(originColor); |
|
} |
|
} |
|
@Override |
|
public void mousePressed(MouseEvent e) { |
|
if (e.getX() < ARROW_RANGE_START) { |
|
mouseDownCompCoords = e.getPoint(); |
|
} |
|
} |
|
}; |
|
|
|
private MouseMotionListener mouseMotionListener = new MouseMotionListener() { |
|
@Override |
|
public void mouseMoved(MouseEvent e) { |
|
if (e.getX() >= ARROW_RANGE_START) { |
|
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); |
|
} else if (isMovable) { |
|
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); |
|
contentPane.setBackground(UIConstants.POPUP_TITLE_BACKGROUND); |
|
} else { |
|
setCursor(Cursor.getDefaultCursor()); |
|
} |
|
repaint(); |
|
} |
|
@Override |
|
public void mouseDragged(MouseEvent e) { |
|
if (isMovable && mouseDownCompCoords != null) { |
|
Point currCoords = e.getLocationOnScreen(); |
|
int x = currCoords.x - mouseDownCompCoords.x; |
|
int y = currCoords.y - mouseDownCompCoords.y; |
|
//屏幕可用区域 |
|
Rectangle screen = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(); |
|
|
|
int minY = screen.y; |
|
int maxX = Toolkit.getDefaultToolkit().getScreenSize().width - MAX_X_SHIFT; |
|
int maxY = Toolkit.getDefaultToolkit().getScreenSize().height - MAX_Y_SHIFT; |
|
if (x < MIN_X) { |
|
x = MIN_X; |
|
} else if (x > maxX) { |
|
x = maxX; |
|
} |
|
if (y < minY) { |
|
y = minY; |
|
} else if (y > maxY) { |
|
y = maxY; |
|
} |
|
// 移动到屏幕边缘时,需要校正位置 |
|
parentDialog.setLocation(x, y); |
|
} |
|
} |
|
}; |
|
|
|
public PopupToolPane(PropertyItem propertyItem) { |
|
this(propertyItem, NO_BUTTON); |
|
} |
|
|
|
public PopupToolPane(PropertyItem propertyItem, String buttonType) { |
|
super(); |
|
this.propertyItem = propertyItem; |
|
this.title = propertyItem.getTitle(); |
|
originColor = UIConstants.UI_TOOLBAR_COLOR; |
|
|
|
contentPane = new JPanel(); |
|
contentPane.setBackground(originColor); |
|
contentPane.setLayout(new BorderLayout()); |
|
UILabel label = new UILabel(title); |
|
contentPane.add(label, BorderLayout.WEST); |
|
contentPane.setBorder(new EmptyBorder(5, 10, 5, 0)); |
|
|
|
setLayout(new BorderLayout()); |
|
add(contentPane, BorderLayout.CENTER); |
|
setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIConstants.TOOLBAR_BORDER_COLOR)); |
|
initToolButton(buttonType); |
|
} |
|
|
|
public void setParentDialog(JDialog parentDialog) { |
|
this.parentDialog = parentDialog; |
|
isMovable = true; |
|
} |
|
|
|
private void initToolButton(final String buttonType) { |
|
this.buttonType = buttonType; |
|
if (StringUtils.isEmpty(buttonType) || buttonType.equals(NO_BUTTON)) { |
|
return; |
|
} |
|
// validate |
|
if (!buttonType.equals(UP_BUTTON) && !buttonType.equals(DOWN_BUTTON)) { |
|
throw new IllegalArgumentException("unknown button type: " + buttonType); |
|
} |
|
addMouseMotionListener(mouseMotionListener); |
|
addMouseListener(mouseListener); |
|
} |
|
|
|
// 触发弹入、弹出 |
|
private void onPop() { |
|
if (buttonType.equals(DOWN_BUTTON)) { |
|
propertyItem.popupDialog(); |
|
} else if (buttonType.equals(UP_BUTTON)) { |
|
propertyItem.popToFrame(); |
|
} |
|
} |
|
|
|
@Override |
|
public Dimension getPreferredSize() { |
|
return new Dimension(super.getPreferredSize().width, POPUP_TOOLPANE_HEIGHT); |
|
} |
|
|
|
@Override |
|
public void paint(Graphics g) { |
|
super.paint(g); |
|
Image button; |
|
g.setColor(new Color(69, 135, 255)); |
|
g.setFont(FRFont.getInstance().applySize(14)); |
|
if (buttonType.equals(NO_BUTTON)) { |
|
return; |
|
} |
|
if (buttonType.equals(DOWN_BUTTON)) { |
|
button = UIConstants.POP_BUTTON_DOWN; |
|
} else { |
|
button = UIConstants.POP_BUTTON_UP; |
|
} |
|
g.drawImage(button, ARROW_RANGE_START + 8, 4, 16, 16, null); |
|
} |
|
} |
|
|
|
private class PopupDialog extends JDialog { |
|
private Container container; |
|
private static final int RESIZE_RANGE = 8; |
|
private Cursor originCursor; |
|
private Cursor southResizeCursor = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR); |
|
private Point mouseDownCompCoords; |
|
private JPanel contentWrapper; |
|
|
|
private Container contentPane; |
|
private JPanel defaultPane; // 无可用配置项 |
|
private PropertyItem propertyItem; |
|
public PopupDialog(PropertyItem propertyItem) { |
|
super(DesignerContext.getDesignerFrame()); |
|
container = getContentPane(); |
|
setUndecorated(true); |
|
this.propertyItem = propertyItem; |
|
PopupToolPane popupToolPane = new PopupToolPane(propertyItem, PopupToolPane.UP_BUTTON); |
|
popupToolPane.setParentDialog(this); |
|
contentPane = propertyItem.getContentArea(); |
|
|
|
contentWrapper = new JPanel(new BorderLayout()); |
|
contentWrapper.add(popupToolPane, BorderLayout.NORTH); |
|
contentWrapper.add(contentPane, BorderLayout.CENTER); |
|
contentWrapper.setBorder(BorderFactory.createLineBorder(UIConstants.PROPERTY_DIALOG_BORDER)); |
|
|
|
JPanel horizontalToolPane = new JPanel() { |
|
@Override |
|
public void paint(Graphics g) { |
|
g.drawImage(UIConstants.DRAG_BAR, 0, 0, getWidth(), getHeight(), null); |
|
g.drawImage(UIConstants.DRAG_DOT, (getWidth() - RESIZE_RANGE) / 2, 3, RESIZE_RANGE, 5, null); |
|
} |
|
}; |
|
contentWrapper.add(horizontalToolPane, BorderLayout.SOUTH); |
|
|
|
container.add(contentWrapper, BorderLayout.CENTER); |
|
setSize(CONTENT_WIDTH, POPUP_DEFAULT_HEIGHT + RESIZE_RANGE); |
|
adjustLocation(); |
|
|
|
initListener(); |
|
this.setVisible(true); |
|
|
|
defaultPane = getDefaultPane(Inter.getLocText("FR-Designer_No_Settings_Available")); |
|
} |
|
|
|
public void showDefaultPane() { |
|
replaceContentPane(defaultPane); |
|
} |
|
|
|
public void adjustLocation() { |
|
this.setLocation( |
|
getLeftPane().getLocationOnScreen().x - CONTENT_WIDTH, |
|
DesignerContext.getDesignerFrame().getLocationOnScreen().y + 228 |
|
); |
|
} |
|
|
|
public void replaceContentPane(PropertyItem propertyItem) { |
|
this.propertyItem = propertyItem; |
|
replaceContentPane(propertyItem.getContentArea()); |
|
} |
|
|
|
public void replaceContentPane(Container contentPane) { |
|
contentWrapper.remove(this.contentPane); |
|
contentWrapper.add(this.contentPane = contentPane, BorderLayout.CENTER); |
|
refreshContainer(); |
|
} |
|
|
|
private void refreshContainer() { |
|
validate(); |
|
repaint(); |
|
revalidate(); |
|
} |
|
|
|
private void initListener() { |
|
addMouseMotionListener(new MouseMotionListener() { |
|
@Override |
|
public void mouseDragged(MouseEvent e) { |
|
if (mouseDownCompCoords != null) { |
|
Rectangle bounds = getBounds(); |
|
Point currCoords = e.getLocationOnScreen(); |
|
bounds.height = currCoords.y - mouseDownCompCoords.y + bounds.height; |
|
// 校正位置 |
|
if (bounds.height < POPUP_MIN_HEIGHT) { |
|
bounds.height = POPUP_MIN_HEIGHT; |
|
} |
|
mouseDownCompCoords.y = currCoords.y; |
|
setBounds(bounds); |
|
} |
|
} |
|
|
|
@Override |
|
public void mouseMoved(MouseEvent e) { |
|
if (originCursor == null) { // 记录最初的光标 |
|
originCursor = getCursor(); |
|
} |
|
if (e.getY() > getHeight() - RESIZE_RANGE) { |
|
setCursor(southResizeCursor); |
|
} else { |
|
// 还原 |
|
if (mouseDownCompCoords == null && getCursor().equals(southResizeCursor)) { |
|
setCursor(originCursor); |
|
} |
|
} |
|
|
|
repaint(); |
|
} |
|
}); |
|
addMouseListener(new MouseAdapter() { |
|
@Override |
|
public void mousePressed(MouseEvent e) { |
|
if (getCursor().equals(southResizeCursor)) { |
|
mouseDownCompCoords = e.getLocationOnScreen(); |
|
} |
|
} |
|
@Override |
|
public void mouseReleased(MouseEvent e) { |
|
mouseDownCompCoords = null; |
|
} |
|
}); |
|
} |
|
} |
|
} |