Browse Source

Merge branch 'feature/x' of ssh://code.fineres.com:7999/~fanglei/design into feature/x

* 'feature/x' of ssh://code.fineres.com:7999/~fanglei/design:
  REPORT-62440 表头排序内置
  REPORT-64445 新老自适应配置面板修改
  REPORT-58833 js编辑器
  REPORT-58833 js编辑器
  REPORT-65474 设计器-水印,平台改变水印开关,模板水印变成了模板单独设置 1.新建水印默认不是模板水印,当新建模板水印的时候,进行配置即可。
  REPORT-65449 在组件包详情页拖拽组件并修改后,再点到在线组件,标签和内容显示不一致
  REPORT-64811 10.0设计器下载的组件文件无法解压缩
  REPORT-65290 设计器-水印,平台改变水印开关,模板水印变成了模板单独设置 1.修改水印的isvalid
  REPORT-65369 设计器内对macOS12的处理-按钮图标设置-在点击 选择图片时回到了父弹窗界面,没有实时显示出来,而需要再次单机设计器界面
  REPORT-65381 linux_arm设计器-点击菜单栏文件-选项,出现弹窗后再点击 确定按钮,弹窗不消失,无任何反应
  REPORT-65371 【主题边框】附件截图,滚动条显示有问题
  REPORT-65343 FR11-新自适应开发者调试-新建模板,直接点击开发者调试进行模板保存和预览,此时虽然弹出保存路径弹窗,但对话框弹窗还没有点击的时候模板web就打开了且报错,因为模板没保存成功;设计器端可以看到模板被关闭了
  REPORT-65365 【主题边框】多次切换单元格样式后切换自定义,边框线有问题
  REPORT-65358 【主题边框】单元格样式双线显示有问题
  REPORT-65307 二轮冒烟测试-远程模板锁定优化-国际化问题-弹窗显示不全
  删除无用接口
  REPORT-64009 设计器内对macOS12的处理 fix import
  REPORT-64009 设计器内对macOS12的处理 fix门槛用例的bug
  REPORT-65107 决策报表-11frm,无法向tab组件上方拖入放置组件,10上操作还比较顺畅

# Conflicts:
#	designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java
feature/x
方磊 3 years ago
parent
commit
e5e3e838a4
  1. 2
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  2. 25
      designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java
  3. 10
      designer-base/src/main/java/com/fr/design/formula/FormulaPane.java
  4. 5
      designer-base/src/main/java/com/fr/design/gui/autocomplete/AutoCompleteExtraRefreshComponent.java
  5. 982
      designer-base/src/main/java/com/fr/design/gui/autocomplete/AutoCompleteWithExtraRefreshPopupWindow.java
  6. 1260
      designer-base/src/main/java/com/fr/design/gui/autocomplete/AutoCompletionWithExtraRefresh.java
  7. 976
      designer-base/src/main/java/com/fr/design/gui/autocomplete/FormulaAutoCompletePopupWindow.java
  8. 1241
      designer-base/src/main/java/com/fr/design/gui/autocomplete/FormulaPaneAutoCompletion.java
  9. 16
      designer-base/src/main/java/com/fr/design/gui/autocomplete/JSAutoCompletePopupWindow.java
  10. 31
      designer-base/src/main/java/com/fr/design/gui/autocomplete/JSImplPaneAutoCompletion.java
  11. 78
      designer-base/src/main/java/com/fr/design/gui/ilable/UIAutoChangeLineLabel.java
  12. 13
      designer-base/src/main/java/com/fr/design/gui/style/BorderPane.java
  13. 167
      designer-base/src/main/java/com/fr/design/javascript/JSContentPane.java
  14. 858
      designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java
  15. 95
      designer-base/src/main/java/com/fr/design/javascript/JavaScriptImplPane.java
  16. 23
      designer-base/src/main/java/com/fr/design/javascript/NewJavaScriptImplPane.java
  17. 21
      designer-base/src/main/java/com/fr/design/javascript/jsapi/CategoryTreeNodesUserObject.java
  18. 155
      designer-base/src/main/java/com/fr/design/javascript/jsapi/JSAPITreeHelper.java
  19. 9
      designer-base/src/main/java/com/fr/design/javascript/jsapi/JSAPIUserObject.java
  20. 7
      designer-base/src/main/java/com/fr/design/javascript/jsapi/JSImplPopulateAction.java
  21. 7
      designer-base/src/main/java/com/fr/design/javascript/jsapi/JSImplUpdateAction.java
  22. 3
      designer-base/src/main/java/com/fr/design/lock/LockInfoDialog.java
  23. 3
      designer-base/src/main/java/com/fr/design/mainframe/ForbiddenPane.java
  24. 2
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java
  25. 6
      designer-base/src/main/java/com/fr/design/report/WatermarkSettingPane.java
  26. 6
      designer-base/src/main/java/com/fr/design/report/fit/AdaptiveFrmFitAttrModel.java
  27. 130
      designer-base/src/main/java/com/fr/design/report/fit/BaseFitAttrPane.java
  28. 9
      designer-base/src/main/java/com/fr/design/report/fit/FitAttrModel.java
  29. 11
      designer-base/src/main/java/com/fr/design/report/fit/FitType.java
  30. 128
      designer-base/src/main/java/com/fr/design/report/fit/FormFitAttrModelType.java
  31. 59
      designer-base/src/main/java/com/fr/design/report/fit/FormFitConfigPane.java
  32. 9
      designer-base/src/main/java/com/fr/design/report/fit/FrmFitAttrModel.java
  33. 71
      designer-base/src/main/java/com/fr/design/report/fit/NewFitPreviewPane.java
  34. 172
      designer-base/src/main/java/com/fr/design/report/fit/ReportFitConfigPane.java
  35. 41
      designer-base/src/main/java/com/fr/design/web/CustomIconPane.java
  36. 9
      designer-base/src/main/java/com/fr/design/worker/save/CallbackSaveWorker.java
  37. 4
      designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties
  38. 4
      designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties
  39. 4
      designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties
  40. 4
      designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties
  41. 4
      designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties
  42. 47
      designer-base/src/main/resources/com/fr/design/javascript/jsapi/category.json
  43. 33
      designer-base/src/main/resources/com/fr/design/javascript/jsapi/jsapi.json
  44. 31
      designer-base/src/test/java/com/fr/design/javascript/jsapi/JSAPITreeHelperTest.java
  45. 17
      designer-base/src/test/resources/com/fr/design/javascript/jsapi/category.json
  46. 8
      designer-base/src/test/resources/com/fr/design/javascript/jsapi/jsapi.json
  47. 8
      designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java
  48. 12
      designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java
  49. 9
      designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java
  50. 13
      designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTitleLayout.java
  51. 85
      designer-form/src/main/java/com/fr/design/fit/FormFitAttrAction.java
  52. 377
      designer-form/src/main/java/com/fr/design/fit/FormFitAttrPane.java
  53. 14
      designer-form/src/main/java/com/fr/design/mainframe/JForm.java
  54. 6
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetTabPane.java
  55. 19
      designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java
  56. 110
      designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteBodyLayoutDefinePane.java
  57. 54
      designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteLayoutDefinePane.java
  58. 118
      designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRFitLayoutDefinePane.java
  59. 151
      designer-realize/src/main/java/com/fr/design/dscolumn/DSColumnAdvancedPane.java
  60. 2
      designer-realize/src/main/java/com/fr/design/javascript/ListenerEditPane.java
  61. 114
      designer-realize/src/main/java/com/fr/design/mainframe/cell/AbstractDSCellEditorPane.java
  62. 20
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellExpandAttrPane.java
  63. 40
      designer-realize/src/main/java/com/fr/design/sort/celldscolumn/CellDSColumnSortGroupPane.java
  64. 40
      designer-realize/src/main/java/com/fr/design/sort/celldscolumn/CellDSColumnSortItemPane.java
  65. 62
      designer-realize/src/main/java/com/fr/design/sort/celldscolumn/CellDSColumnSortPane.java
  66. 19
      designer-realize/src/main/java/com/fr/design/sort/cellexpand/CellExpandSortGroupPane.java
  67. 37
      designer-realize/src/main/java/com/fr/design/sort/cellexpand/CellExpandSortItemPane.java
  68. 39
      designer-realize/src/main/java/com/fr/design/sort/cellexpand/CellExpandSortPane.java
  69. 152
      designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortGroupPane.java
  70. 153
      designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortItemPane.java
  71. 112
      designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortPane.java
  72. 277
      designer-realize/src/main/java/com/fr/design/sort/common/SortColumnRowPane.java
  73. 119
      designer-realize/src/main/java/com/fr/design/sort/common/SortUIExpandablePane.java
  74. 32
      designer-realize/src/main/java/com/fr/design/sort/expressionpane/CellSortExpressionPane.java
  75. 190
      designer-realize/src/main/java/com/fr/design/sort/expressionpane/CustomSequenceEditPane.java
  76. 66
      designer-realize/src/main/java/com/fr/design/sort/expressionpane/CustomSequencePane.java
  77. 37
      designer-realize/src/main/java/com/fr/design/sort/expressionpane/CustomSequenceSortExpressionPane.java
  78. 42
      designer-realize/src/main/java/com/fr/design/sort/expressionpane/FormulaSortExpressionPane.java
  79. 23
      designer-realize/src/main/java/com/fr/design/sort/expressionpane/SortExpressionPane.java
  80. 267
      designer-realize/src/main/java/com/fr/design/sort/header/HeaderAreaPane.java
  81. 81
      designer-realize/src/main/java/com/fr/design/sort/header/HeaderSettingPane.java
  82. 279
      designer-realize/src/main/java/com/fr/design/sort/header/HeaderSortRulePane.java
  83. 65
      designer-realize/src/main/java/com/fr/design/sort/header/SortHeaderPane.java
  84. 367
      designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellDSColumnEditor.java
  85. 4
      designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

2
designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java

@ -809,7 +809,7 @@ public class PreferencePane extends BasicPane {
designerEnvManager.setJoinProductImprove(this.joinProductImproveCheckBox.isSelected());
designerEnvManager.setEmbedServerLazyStartup(this.embedServerLazyStartupCheckBox.isSelected());
designerEnvManager.setImageCompress(this.imageCompressPanelCheckBox.isSelected());
designerEnvManager.setUseOptimizedUPM4Adapter(this.useOptimizedUPMCheckbox.isSelected());
designerEnvManager.setUseOptimizedUPM4Adapter(this.useOptimizedUPMCheckbox != null && this.useOptimizedUPMCheckbox.isSelected());
VcsConfigManager vcsConfigManager = designerEnvManager.getVcsConfigManager();
vcsConfigManager.setSaveInterval(this.saveIntervalEditor.getValue());
vcsConfigManager.setVcsEnable(this.vcsEnableCheckBox.isSelected());

25
designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java

@ -19,9 +19,7 @@ import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.List;
@ -154,16 +152,16 @@ public class CellStylePreviewPane extends JPanel {
float adjustRight = 0;
float adjustBottom = 0;
if (column == 0) {
adjustLeft = GraphHelper.getLineStyleSize(style.getBorderLeft()) / 2.0F + computeOffset4DoubleStyleBorder(style);
adjustLeft = computeHalfSize4StyledBorder(style.getBorderLeft());
}
if (row == 0) {
adjustTop = GraphHelper.getLineStyleSize(style.getBorderTop()) / 2.0F + computeOffset4DoubleStyleBorder(style);
adjustTop = computeHalfSize4StyledBorder(style.getBorderTop());
}
if (column == columnSpan - 1) {
adjustRight = -GraphHelper.getLineStyleSize(style.getBorderRight()) / 2.0F - computeOffset4DoubleStyleBorder(style);
adjustRight = -computeHalfSize4StyledBorder(style.getBorderRight());
}
if (row == rowSpan - 1) {
adjustBottom = -GraphHelper.getLineStyleSize(style.getBorderBottom()) / 2.0F - computeOffset4DoubleStyleBorder(style);
adjustBottom = -computeHalfSize4StyledBorder(style.getBorderBottom());
}
g2d.translate(adjustLeft, adjustTop);
@ -171,15 +169,16 @@ public class CellStylePreviewPane extends JPanel {
g2d.translate(-adjustLeft, -adjustTop);
}
private float computeOffset4DoubleStyleBorder(Style style) {
float offset = 0F;
if (style.getBorderLeft() == Constants.LINE_DOUBLE) {
offset += GraphHelper.getLineStyleSize(Constants.LINE_THIN) / 2.0F;
} else if (style.getBorderLeft() == Constants.LINE_DOUBLE_DOT) {
offset += GraphHelper.getLineStyleSize(Constants.LINE_DOT) / 2.0F;
private float computeHalfSize4StyledBorder(int border) {
float size = GraphHelper.getLineStyleSize(border) / 2.0F;
if (border == Constants.LINE_DOUBLE) {
size += GraphHelper.getLineStyleSize(Constants.LINE_THIN) / 2.0F;
} else if (border == Constants.LINE_DOUBLE_DOT) {
size += GraphHelper.getLineStyleSize(Constants.LINE_DOT) / 2.0F;
}
return offset;
return size;
}
@Override

10
designer-base/src/main/java/com/fr/design/formula/FormulaPane.java

@ -16,6 +16,7 @@ import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.autocomplete.AutoCompleteExtraRefreshComponent;
import com.fr.design.gui.autocomplete.CompletionCellRenderer;
import com.fr.design.gui.autocomplete.CompletionProvider;
import com.fr.design.gui.autocomplete.DefaultCompletionProvider;
@ -416,7 +417,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
autoCompletion = new FormulaPaneAutoCompletion(provider);
autoCompletion.setListCellRenderer(new CompletionCellRenderer());
autoCompletion.install(formulaTextArea);
autoCompletion.installVariableTree(variableTreeAndDescriptionArea);
autoCompletion.installExtraRefreshComponent(variableTreeAndDescriptionArea);
}
@ -1036,7 +1037,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
}
}
public class VariableTreeAndDescriptionArea extends JPanel {
public class VariableTreeAndDescriptionArea extends JPanel implements AutoCompleteExtraRefreshComponent {
private JTree variablesTree;
private UITextArea descriptionTextArea;
@ -1277,6 +1278,11 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
functionTypeList.setSelectedIndex(0);
}
@Override
public void refresh(String replacementText) {
refreshText(replacementText);
}
/*
* 查看函数的详细信息
*/

5
designer-base/src/main/java/com/fr/design/gui/autocomplete/AutoCompleteExtraRefreshComponent.java

@ -0,0 +1,5 @@
package com.fr.design.gui.autocomplete;
public interface AutoCompleteExtraRefreshComponent {
void refresh(String replacementText);
}

982
designer-base/src/main/java/com/fr/design/gui/autocomplete/AutoCompleteWithExtraRefreshPopupWindow.java

@ -0,0 +1,982 @@
package com.fr.design.gui.autocomplete;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.PopupWindowDecorator;
import com.fr.log.FineLoggerFactory;
import java.awt.BorderLayout;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JWindow;
import javax.swing.KeyStroke;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.ListUI;
import javax.swing.text.Caret;
import javax.swing.text.JTextComponent;
public abstract class AutoCompleteWithExtraRefreshPopupWindow extends JWindow implements CaretListener,
ListSelectionListener, MouseListener {
private final static int DIS = 5;
/**
* The parent AutoCompletion instance.
*/
private AutoCompletion ac;
/**
* The list of completion choices.
*/
private JList list;
/**
* The contents of {@link #list()}.
*/
private CompletionListModel model;
/**
* A hack to work around the fact that we clear our completion model (and
* our selection) when hiding the completion window. This allows us to
* still know what the user selected after the popup is hidden.
*/
private Completion lastSelection;
/**
* Optional popup window containing a description of the currently
* selected completion.
*/
private AutoCompleteDescWindow descWindow;
/**
* The preferred size of the optional description window. This field
* only exists because the user may (and usually will) set the size of
* the description window before it exists (it must be parented to a
* Window).
*/
private Dimension preferredDescWindowSize;
/**
* Whether the completion window and the optional description window
* should be displayed above the current caret position (as opposed to
* underneath it, which is preferred unless there is not enough space).
*/
private boolean aboveCaret;
private int lastLine;
private KeyActionPair escapeKap;
private KeyActionPair upKap;
private KeyActionPair downKap;
private KeyActionPair leftKap;
private KeyActionPair rightKap;
private KeyActionPair enterKap;
private KeyActionPair tabKap;
private KeyActionPair homeKap;
private KeyActionPair endKap;
private KeyActionPair pageUpKap;
private KeyActionPair pageDownKap;
private KeyActionPair ctrlCKap;
private KeyActionPair oldEscape, oldUp, oldDown, oldLeft, oldRight,
oldEnter, oldTab, oldHome, oldEnd, oldPageUp, oldPageDown,
oldCtrlC;
/**
* The space between the caret and the completion popup.
*/
private static final int VERTICAL_SPACE = 1;
/**
* The class name of the Substance List UI.
*/
private static final String SUBSTANCE_LIST_UI =
"org.pushingpixels.substance.internal.ui.SubstanceListUI";
protected AutoCompleteExtraRefreshComponent component;
/**
* Constructor.
*
* @param parent The parent window (hosting the text component).
* @param ac The auto-completion instance.
*/
public AutoCompleteWithExtraRefreshPopupWindow(Window parent, final AutoCompletion ac) {
super(parent);
ComponentOrientation o = ac.getTextComponentOrientation();
this.ac = ac;
model = new CompletionListModel();
list = new PopupList(model);
list.setCellRenderer(new DelegatingCellRenderer());
list.addListSelectionListener(this);
list.addMouseListener(this);
JPanel contentPane = new JPanel(new BorderLayout());
JScrollPane sp = new JScrollPane(list,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
// In 1.4, JScrollPane.setCorner() has a bug where it won't accept
// JScrollPane.LOWER_TRAILING_CORNER, even though that constant is
// defined. So we have to put the logic added in 1.5 to handle it
// here.
JPanel corner = new SizeGrip();
//sp.setCorner(JScrollPane.LOWER_TRAILING_CORNER, corner);
boolean isLeftToRight = o.isLeftToRight();
String str = isLeftToRight ? JScrollPane.LOWER_RIGHT_CORNER :
JScrollPane.LOWER_LEFT_CORNER;
sp.setCorner(str, corner);
contentPane.add(sp);
setContentPane(contentPane);
applyComponentOrientation(o);
// Give apps a chance to decorate us with drop shadows, etc.
if (Util.getShouldAllowDecoratingMainAutoCompleteWindows()) {
PopupWindowDecorator decorator = PopupWindowDecorator.get();
if (decorator != null) {
decorator.decorate(this);
}
}
pack();
setFocusableWindowState(false);
lastLine = -1;
}
public void caretUpdate(CaretEvent e) {
if (isVisible()) { // Should always be true
int line = ac.getLineOfCaret();
if (line != lastLine) {
lastLine = -1;
setVisible(false);
} else {
doAutocomplete();
}
} else if (AutoCompletion.isDebug()) {
Thread.dumpStack();
}
}
/**
* Creates the description window.
*
* @return The description window.
*/
private AutoCompleteDescWindow createDescriptionWindow() {
AutoCompleteDescWindow dw = new AutoCompleteDescWindow(this, ac);
dw.applyComponentOrientation(ac.getTextComponentOrientation());
Dimension size = preferredDescWindowSize;
if (size == null) {
size = getSize();
}
dw.setSize(size);
return dw;
}
/**
* Creates the mappings from keys to Actions we'll be putting into the
* text component's ActionMap and InputMap.
*/
private void createKeyActionPairs() {
// Actions we'll install.
EnterAction enterAction = new EnterAction();
escapeKap = new KeyActionPair("Escape", new EscapeAction());
upKap = new KeyActionPair("Up", new UpAction());
downKap = new KeyActionPair("Down", new DownAction());
leftKap = new KeyActionPair("Left", new LeftAction());
rightKap = new KeyActionPair("Right", new RightAction());
enterKap = new KeyActionPair("Enter", enterAction);
tabKap = new KeyActionPair("Tab", enterAction);
homeKap = new KeyActionPair("Home", new HomeAction());
endKap = new KeyActionPair("End", new EndAction());
pageUpKap = new KeyActionPair("PageUp", new PageUpAction());
pageDownKap = new KeyActionPair("PageDown", new PageDownAction());
ctrlCKap = new KeyActionPair("CtrlC", new CopyAction());
// Buffers for the actions we replace.
oldEscape = new KeyActionPair();
oldUp = new KeyActionPair();
oldDown = new KeyActionPair();
oldLeft = new KeyActionPair();
oldRight = new KeyActionPair();
oldEnter = new KeyActionPair();
oldTab = new KeyActionPair();
oldHome = new KeyActionPair();
oldEnd = new KeyActionPair();
oldPageUp = new KeyActionPair();
oldPageDown = new KeyActionPair();
oldCtrlC = new KeyActionPair();
}
protected void doAutocomplete() {
lastLine = ac.refreshPopupWindow();
}
/**
* Returns the copy keystroke to use for this platform.
*
* @return The copy keystroke.
*/
private static final KeyStroke getCopyKeyStroke() {
int key = KeyEvent.VK_C;
int mask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
return KeyStroke.getKeyStroke(key, mask);
}
/**
* Returns the default list cell renderer used when a completion provider
* does not supply its own.
*
* @return The default list cell renderer.
* @see #setListCellRenderer(ListCellRenderer)
*/
public ListCellRenderer getListCellRenderer() {
DelegatingCellRenderer dcr = (DelegatingCellRenderer) list.
getCellRenderer();
return dcr.getFallbackCellRenderer();
}
/**
* Returns the selected value, or <code>null</code> if nothing is selected.
*
* @return The selected value.
*/
public Completion getSelection() {
return isShowing() ? (Completion) list.getSelectedValue() : lastSelection;
}
/**
* Inserts the currently selected completion.
*
* @see #getSelection()
*/
private void insertSelectedCompletion() {
Completion comp = getSelection();
ac.insertCompletion(comp);
}
public void installComp(AutoCompleteExtraRefreshComponent component){
this.component = component;
}
public void refreshInstallComp() {
component.refresh(getSelection().getReplacementText());
}
/**
* Registers keyboard actions to listen for in the text component and
* intercept.
*
* @see #uninstallKeyBindings()
*/
private void installKeyBindings() {
if (AutoCompletion.isDebug()) {
FineLoggerFactory.getLogger().debug("PopupWindow: Installing keybindings");
}
if (escapeKap == null) { // Lazily create actions.
createKeyActionPairs();
}
JTextComponent comp = ac.getTextComponent();
InputMap im = comp.getInputMap();
ActionMap am = comp.getActionMap();
replaceAction(im, am, KeyEvent.VK_ESCAPE, escapeKap, oldEscape);
if (AutoCompletion.isDebug() && oldEscape.action == escapeKap.action) {
Thread.dumpStack();
}
replaceAction(im, am, KeyEvent.VK_UP, upKap, oldUp);
replaceAction(im, am, KeyEvent.VK_LEFT, leftKap, oldLeft);
replaceAction(im, am, KeyEvent.VK_DOWN, downKap, oldDown);
replaceAction(im, am, KeyEvent.VK_RIGHT, rightKap, oldRight);
replaceAction(im, am, KeyEvent.VK_ENTER, enterKap, oldEnter);
replaceAction(im, am, KeyEvent.VK_TAB, tabKap, oldTab);
replaceAction(im, am, KeyEvent.VK_HOME, homeKap, oldHome);
replaceAction(im, am, KeyEvent.VK_END, endKap, oldEnd);
replaceAction(im, am, KeyEvent.VK_PAGE_UP, pageUpKap, oldPageUp);
replaceAction(im, am, KeyEvent.VK_PAGE_DOWN, pageDownKap, oldPageDown);
// Make Ctrl+C copy from description window. This isn't done
// automagically because the desc. window is not focusable, and copying
// from text components can only be done from focused components.
KeyStroke ks = getCopyKeyStroke();
oldCtrlC.key = im.get(ks);
im.put(ks, ctrlCKap.key);
oldCtrlC.action = am.get(ctrlCKap.key);
am.put(ctrlCKap.key, ctrlCKap.action);
comp.addCaretListener(this);
}
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2 && e.getButton() == 1) {
insertSelectedCompletion();
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
refreshInstallComp();
}
public void mouseReleased(MouseEvent e) {
}
/**
* Positions the description window relative to the completion choices
* window. We assume there is room on one side of the other for this
* entire window to fit.
*/
private void positionDescWindow() {
boolean showDescWindow = descWindow != null && ac.isShowDescWindow();
if (!showDescWindow) {
return;
}
// Don't use getLocationOnScreen() as this throws an exception if
// window isn't visible yet, but getLocation() doesn't, and is in
// screen coordinates!
Point p = getLocation();
Rectangle screenBounds = Util.getScreenBoundsForPoint(p.x, p.y);
//Dimension screenSize = getToolkit().getScreenSize();
//int totalH = Math.max(getHeight(), descWindow.getHeight());
// Try to position to the right first (LTR)
int x;
if (ac.getTextComponentOrientation().isLeftToRight()) {
x = getX() + getWidth() + DIS;
if (x + descWindow.getWidth() > screenBounds.x + screenBounds.width) { // doesn't fit
x = getX() - DIS - descWindow.getWidth();
}
} else { // RTL
x = getX() - DIS - descWindow.getWidth();
if (x < screenBounds.x) { // Doesn't fit
x = getX() + getWidth() + DIS;
}
}
int y = getY();
if (aboveCaret) {
y = y + getHeight() - descWindow.getHeight();
}
if (x != descWindow.getX() || y != descWindow.getY()) {
descWindow.setLocation(x, y);
}
}
/**
* "Puts back" the original key/Action pair for a keystroke. This is used
* when this popup is hidden.
*
* @param im The input map.
* @param am The action map.
* @param key The keystroke whose key/Action pair to change.
* @param kap The (original) key/Action pair.
* @see #replaceAction(InputMap, ActionMap, int, KeyActionPair, KeyActionPair)
*/
private void putBackAction(InputMap im, ActionMap am, int key,
KeyActionPair kap) {
KeyStroke ks = KeyStroke.getKeyStroke(key, 0);
am.put(im.get(ks), kap.action); // Original action for the "new" key
im.put(ks, kap.key); // Original key for the keystroke.
}
/**
* Replaces a key/Action pair in an InputMap and ActionMap with a new
* pair.
*
* @param im The input map.
* @param am The action map.
* @param key The keystroke whose information to replace.
* @param kap The new key/Action pair for <code>key</code>.
* @param old A buffer in which to place the old key/Action pair.
* @see #putBackAction(InputMap, ActionMap, int, KeyActionPair)
*/
private void replaceAction(InputMap im, ActionMap am, int key,
KeyActionPair kap, KeyActionPair old) {
KeyStroke ks = KeyStroke.getKeyStroke(key, 0);
old.key = im.get(ks);
im.put(ks, kap.key);
old.action = am.get(kap.key);
am.put(kap.key, kap.action);
}
/**
* Selects the first item in the completion list.
*
* @see #selectLastItem()
*/
private void selectFirstItem() {
if (model.getSize() > 0) {
list.setSelectedIndex(0);
list.ensureIndexIsVisible(0);
}
}
/**
* Selects the last item in the completion list.
*
* @see #selectFirstItem()
*/
private void selectLastItem() {
int index = model.getSize() - 1;
if (index > -1) {
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
}
/**
* Selects the next item in the completion list.
*
* @see #selectPreviousItem()
*/
private void selectNextItem() {
int index = list.getSelectedIndex();
if (index > -1) {
index = (index + 1) % model.getSize();
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
}
/**
* Selects the completion item one "page down" from the currently selected
* one.
*
* @see #selectPageUpItem()
*/
private void selectPageDownItem() {
int visibleRowCount = list.getVisibleRowCount();
int i = Math.min(list.getModel().getSize() - 1,
list.getSelectedIndex() + visibleRowCount);
list.setSelectedIndex(i);
list.ensureIndexIsVisible(i);
}
/**
* Selects the completion item one "page up" from the currently selected
* one.
*
* @see #selectPageDownItem()
*/
private void selectPageUpItem() {
int visibleRowCount = list.getVisibleRowCount();
int i = Math.max(0, list.getSelectedIndex() - visibleRowCount);
list.setSelectedIndex(i);
list.ensureIndexIsVisible(i);
}
/**
* Selects the previous item in the completion list.
*
* @see #selectNextItem()
*/
private void selectPreviousItem() {
int index = list.getSelectedIndex();
switch (index) {
case 0:
index = list.getModel().getSize() - 1;
break;
case -1: // Check for an empty list (would be an error)
index = list.getModel().getSize() - 1;
if (index == -1) {
return;
}
break;
default:
index = index - 1;
break;
}
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
/**
* Sets the completions to display in the choices list. The first
* completion is selected.
*
* @param completions The completions to display.
*/
public void setCompletions(List<Completion> completions) {
model.setContents(completions);
selectFirstItem();
}
/**
* Sets the size of the description window.
*
* @param size The new size. This cannot be <code>null</code>.
*/
public void setDescriptionWindowSize(Dimension size) {
if (descWindow != null) {
descWindow.setSize(size);
} else {
preferredDescWindowSize = size;
}
}
/**
* Sets the default list cell renderer to use when a completion provider
* does not supply its own.
*
* @param renderer The renderer to use. If this is <code>null</code>,
* a default renderer is used.
* @see #getListCellRenderer()
*/
public void setListCellRenderer(ListCellRenderer renderer) {
DelegatingCellRenderer dcr = (DelegatingCellRenderer) list.
getCellRenderer();
dcr.setFallbackCellRenderer(renderer);
}
/**
* Sets the location of this window to be "good" relative to the specified
* rectangle. That rectangle should be the location of the text
* component's caret, in screen coordinates.
*
* @param r The text component's caret position, in screen coordinates.
*/
public void setLocationRelativeTo(Rectangle r) {
// Multi-monitor support - make sure the completion window (and
// description window, if applicable) both fit in the same window in
// a multi-monitor environment. To do this, we decide which monitor
// the rectangle "r" is in, and use that one (just pick top-left corner
// as the defining point).
Rectangle screenBounds = Util.getScreenBoundsForPoint(r.x, r.y);
//Dimension screenSize = getToolkit().getScreenSize();
boolean showDescWindow = descWindow != null && ac.isShowDescWindow();
int totalH = getHeight();
if (showDescWindow) {
totalH = Math.max(totalH, descWindow.getHeight());
}
// Try putting our stuff "below" the caret first. We assume that the
// entire height of our stuff fits on the screen one way or the other.
aboveCaret = false;
int y = r.y + r.height + VERTICAL_SPACE;
if (y + totalH > screenBounds.height) {
y = r.y - VERTICAL_SPACE - getHeight();
aboveCaret = true;
}
// Get x-coordinate of completions. Try to align left edge with the
// caret first.
int x = r.x;
if (!ac.getTextComponentOrientation().isLeftToRight()) {
x -= getWidth(); // RTL => align right edge
}
if (x < screenBounds.x) {
x = screenBounds.x;
} else if (x + getWidth() > screenBounds.x + screenBounds.width) { // completions don't fit
x = screenBounds.x + screenBounds.width - getWidth();
}
setLocation(x, y);
// Position the description window, if necessary.
if (showDescWindow) {
positionDescWindow();
}
}
/**
* Toggles the visibility of this popup window.
*
* @param visible Whether this window should be visible.
*/
@Override
public void setVisible(boolean visible) {
if (visible != isVisible()) {
if (visible) {
installKeyBindings();
lastLine = ac.getLineOfCaret();
selectFirstItem();
if (descWindow == null && ac.isShowDescWindow()) {
descWindow = createDescriptionWindow();
positionDescWindow();
}
// descWindow needs a kick-start the first time it's displayed.
// Also, the newly-selected item in the choices list is
// probably different from the previous one anyway.
if (descWindow != null) {
Completion c = (Completion) list.getSelectedValue();
if (c != null) {
descWindow.setDescriptionFor(c);
}
}
} else {
uninstallKeyBindings();
}
super.setVisible(visible);
// Some languages, such as Java, can use quite a lot of memory
// when displaying hundreds of completion choices. We pro-actively
// clear our list model here to make them available for GC.
// Otherwise, they stick around, and consider the following: a
// user starts code-completion for Java 5 SDK classes, then hides
// the dialog, then changes the "class path" to use a Java 6 SDK
// instead. On pressing Ctrl+space, a new array of Completions is
// created. If this window holds on to the previous Completions,
// you're getting roughly 2x the necessary Completions in memory
// until the Completions are actually passed to this window.
if (!visible) { // Do after super.setVisible(false)
lastSelection = (Completion) list.getSelectedValue();
model.clear();
}
// Must set descWindow's visibility one way or the other each time,
// because of the way child JWindows' visibility is handled - in
// some ways it's dependent on the parent, in other ways it's not.
if (descWindow != null) {
descWindow.setVisible(visible && ac.isShowDescWindow());
}
}
}
/**
* Stops intercepting certain keystrokes from the text component.
*
* @see #installKeyBindings()
*/
private void uninstallKeyBindings() {
if (AutoCompletion.isDebug()) {
FineLoggerFactory.getLogger().debug("PopupWindow: Removing keybindings");
}
JTextComponent comp = ac.getTextComponent();
InputMap im = comp.getInputMap();
ActionMap am = comp.getActionMap();
putBackAction(im, am, KeyEvent.VK_ESCAPE, oldEscape);
putBackAction(im, am, KeyEvent.VK_UP, oldUp);
putBackAction(im, am, KeyEvent.VK_DOWN, oldDown);
putBackAction(im, am, KeyEvent.VK_LEFT, oldLeft);
putBackAction(im, am, KeyEvent.VK_RIGHT, oldRight);
putBackAction(im, am, KeyEvent.VK_ENTER, oldEnter);
putBackAction(im, am, KeyEvent.VK_TAB, oldTab);
putBackAction(im, am, KeyEvent.VK_HOME, oldHome);
putBackAction(im, am, KeyEvent.VK_END, oldEnd);
putBackAction(im, am, KeyEvent.VK_PAGE_UP, oldPageUp);
putBackAction(im, am, KeyEvent.VK_PAGE_DOWN, oldPageDown);
// Ctrl+C
KeyStroke ks = getCopyKeyStroke();
am.put(im.get(ks), oldCtrlC.action); // Original action
im.put(ks, oldCtrlC.key); // Original key
comp.removeCaretListener(this);
}
/**
* Updates the <tt>LookAndFeel</tt> of this window and the description
* window.
*/
public void updateUI() {
SwingUtilities.updateComponentTreeUI(this);
if (descWindow != null) {
descWindow.updateUI();
}
}
/**
* Called when a new item is selected in the popup list.
*
* @param e The event.
*/
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
Object value = list.getSelectedValue();
if (value != null && descWindow != null) {
descWindow.setDescriptionFor((Completion) value);
positionDescWindow();
}
}
}
class CopyAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
boolean doNormalCopy = false;
if (descWindow != null && descWindow.isVisible()) {
doNormalCopy = !descWindow.copy();
}
if (doNormalCopy) {
ac.getTextComponent().copy();
}
}
}
class DownAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
selectNextItem();
refreshInstallComp();
}
}
}
class EndAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
selectLastItem();
}
}
}
class EnterAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
insertSelectedCompletion();
refreshInstallComp();
}
}
}
class EscapeAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
setVisible(false);
}
}
}
class HomeAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
selectFirstItem();
}
}
}
/**
* A mapping from a key (an Object) to an Action.
*/
private static class KeyActionPair {
public Object key;
public Action action;
public KeyActionPair() {
}
public KeyActionPair(Object key, Action a) {
this.key = key;
this.action = a;
}
}
class LeftAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
JTextComponent comp = ac.getTextComponent();
Caret c = comp.getCaret();
int dot = c.getDot();
if (dot > 0) {
c.setDot(--dot);
// Ensure moving left hasn't moved us up a line, thus
// hiding the popup window.
if (comp.isVisible()) {
if (lastLine != -1) {
doAutocomplete();
}
}
}
}
}
}
class PageDownAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
selectPageDownItem();
}
}
}
class PageUpAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
selectPageUpItem();
}
}
}
/**
* The actual list of completion choices in this popup window.
*/
private class PopupList extends JList {
public PopupList(CompletionListModel model) {
super(model);
}
@Override
public void setUI(ListUI ui) {
if (Util.getUseSubstanceRenderers() &&
SUBSTANCE_LIST_UI.equals(ui.getClass().getName())) {
// Substance requires its special ListUI be installed for
// its renderers to actually render (!), but long completion
// lists (e.g. PHPCompletionProvider in RSTALanguageSupport)
// will simply populate too slowly on initial display (when
// calculating preferred size of all items), so in this case
// we give a prototype cell value.
CompletionProvider p = ac.getCompletionProvider();
BasicCompletion bc = new BasicCompletion(p, "Hello world");
setPrototypeCellValue(bc);
} else {
// Our custom UI that is faster for long HTML completion lists.
ui = new FastListUI();
setPrototypeCellValue(null);
}
super.setUI(ui);
}
}
class RightAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
JTextComponent comp = ac.getTextComponent();
Caret c = comp.getCaret();
int dot = c.getDot();
if (dot < comp.getDocument().getLength()) {
c.setDot(++dot);
// Ensure moving right hasn't moved us up a line, thus
// hiding the popup window.
if (comp.isVisible()) {
if (lastLine != -1) {
doAutocomplete();
}
}
}
}
}
}
class UpAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
selectPreviousItem();
refreshInstallComp();
}
}
}
}

1260
designer-base/src/main/java/com/fr/design/gui/autocomplete/AutoCompletionWithExtraRefresh.java

File diff suppressed because it is too large Load Diff

976
designer-base/src/main/java/com/fr/design/gui/autocomplete/FormulaAutoCompletePopupWindow.java

@ -9,41 +9,7 @@
*/
package com.fr.design.gui.autocomplete;
import com.fr.design.formula.FormulaPane;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.PopupWindowDecorator;
import com.fr.log.FineLoggerFactory;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JWindow;
import javax.swing.KeyStroke;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.ListUI;
import javax.swing.text.Caret;
import javax.swing.text.JTextComponent;
import java.awt.BorderLayout;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;
/**
* The actual popup window of choices. When visible, this window intercepts
@ -55,949 +21,11 @@ import java.util.List;
* @author Robert Futrell
* @version 1.0
*/
class FormulaAutoCompletePopupWindow extends JWindow implements CaretListener,
ListSelectionListener, MouseListener {
private final static int DIS = 5;
/**
* The parent AutoCompletion instance.
*/
private FormulaPaneAutoCompletion ac;
/**
* The list of completion choices.
*/
private JList list;
/**
* The contents of {@link #list()}.
*/
private CompletionListModel model;
/**
* A hack to work around the fact that we clear our completion model (and
* our selection) when hiding the completion window. This allows us to
* still know what the user selected after the popup is hidden.
*/
private Completion lastSelection;
/**
* Optional popup window containing a description of the currently
* selected completion.
*/
private AutoCompleteDescWindow descWindow;
/**
* The preferred size of the optional description window. This field
* only exists because the user may (and usually will) set the size of
* the description window before it exists (it must be parented to a
* Window).
*/
private Dimension preferredDescWindowSize;
private FormulaPane.VariableTreeAndDescriptionArea component;
/**
* Whether the completion window and the optional description window
* should be displayed above the current caret position (as opposed to
* underneath it, which is preferred unless there is not enough space).
*/
private boolean aboveCaret;
private int lastLine;
private KeyActionPair escapeKap;
private KeyActionPair upKap;
private KeyActionPair downKap;
private KeyActionPair leftKap;
private KeyActionPair rightKap;
private KeyActionPair enterKap;
private KeyActionPair tabKap;
private KeyActionPair homeKap;
private KeyActionPair endKap;
private KeyActionPair pageUpKap;
private KeyActionPair pageDownKap;
private KeyActionPair ctrlCKap;
private KeyActionPair oldEscape, oldUp, oldDown, oldLeft, oldRight,
oldEnter, oldTab, oldHome, oldEnd, oldPageUp, oldPageDown,
oldCtrlC;
/**
* The space between the caret and the completion popup.
*/
private static final int VERTICAL_SPACE = 1;
/**
* The class name of the Substance List UI.
*/
private static final String SUBSTANCE_LIST_UI =
"org.pushingpixels.substance.internal.ui.SubstanceListUI";
class FormulaAutoCompletePopupWindow extends AutoCompleteWithExtraRefreshPopupWindow {
/**
* Constructor.
*
* @param parent The parent window (hosting the text component).
* @param ac The auto-completion instance.
*/
public FormulaAutoCompletePopupWindow(Window parent, final FormulaPaneAutoCompletion ac) {
super(parent);
ComponentOrientation o = ac.getTextComponentOrientation();
this.ac = ac;
model = new CompletionListModel();
list = new PopupList(model);
list.setCellRenderer(new DelegatingCellRenderer());
list.addListSelectionListener(this);
list.addMouseListener(this);
JPanel contentPane = new JPanel(new BorderLayout());
JScrollPane sp = new JScrollPane(list,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
// In 1.4, JScrollPane.setCorner() has a bug where it won't accept
// JScrollPane.LOWER_TRAILING_CORNER, even though that constant is
// defined. So we have to put the logic added in 1.5 to handle it
// here.
JPanel corner = new SizeGrip();
//sp.setCorner(JScrollPane.LOWER_TRAILING_CORNER, corner);
boolean isLeftToRight = o.isLeftToRight();
String str = isLeftToRight ? JScrollPane.LOWER_RIGHT_CORNER :
JScrollPane.LOWER_LEFT_CORNER;
sp.setCorner(str, corner);
contentPane.add(sp);
setContentPane(contentPane);
applyComponentOrientation(o);
// Give apps a chance to decorate us with drop shadows, etc.
if (Util.getShouldAllowDecoratingMainAutoCompleteWindows()) {
PopupWindowDecorator decorator = PopupWindowDecorator.get();
if (decorator != null) {
decorator.decorate(this);
}
}
pack();
setFocusableWindowState(false);
lastLine = -1;
}
public void caretUpdate(CaretEvent e) {
if (isVisible()) { // Should always be true
int line = ac.getLineOfCaret();
if (line != lastLine) {
lastLine = -1;
setVisible(false);
} else {
doAutocomplete();
}
} else if (AutoCompletion.isDebug()) {
Thread.dumpStack();
}
}
/**
* Creates the description window.
*
* @return The description window.
*/
private AutoCompleteDescWindow createDescriptionWindow() {
AutoCompleteDescWindow dw = new AutoCompleteDescWindow(this, ac);
dw.applyComponentOrientation(ac.getTextComponentOrientation());
Dimension size = preferredDescWindowSize;
if (size == null) {
size = getSize();
}
dw.setSize(size);
return dw;
}
/**
* Creates the mappings from keys to Actions we'll be putting into the
* text component's ActionMap and InputMap.
*/
private void createKeyActionPairs() {
// Actions we'll install.
EnterAction enterAction = new EnterAction();
escapeKap = new KeyActionPair("Escape", new EscapeAction());
upKap = new KeyActionPair("Up", new UpAction());
downKap = new KeyActionPair("Down", new DownAction());
leftKap = new KeyActionPair("Left", new LeftAction());
rightKap = new KeyActionPair("Right", new RightAction());
enterKap = new KeyActionPair("Enter", enterAction);
tabKap = new KeyActionPair("Tab", enterAction);
homeKap = new KeyActionPair("Home", new HomeAction());
endKap = new KeyActionPair("End", new EndAction());
pageUpKap = new KeyActionPair("PageUp", new PageUpAction());
pageDownKap = new KeyActionPair("PageDown", new PageDownAction());
ctrlCKap = new KeyActionPair("CtrlC", new CopyAction());
// Buffers for the actions we replace.
oldEscape = new KeyActionPair();
oldUp = new KeyActionPair();
oldDown = new KeyActionPair();
oldLeft = new KeyActionPair();
oldRight = new KeyActionPair();
oldEnter = new KeyActionPair();
oldTab = new KeyActionPair();
oldHome = new KeyActionPair();
oldEnd = new KeyActionPair();
oldPageUp = new KeyActionPair();
oldPageDown = new KeyActionPair();
oldCtrlC = new KeyActionPair();
}
protected void doAutocomplete() {
lastLine = ac.refreshPopupWindow();
}
/**
* Returns the copy keystroke to use for this platform.
*
* @return The copy keystroke.
*/
private static final KeyStroke getCopyKeyStroke() {
int key = KeyEvent.VK_C;
int mask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
return KeyStroke.getKeyStroke(key, mask);
}
/**
* Returns the default list cell renderer used when a completion provider
* does not supply its own.
*
* @return The default list cell renderer.
* @see #setListCellRenderer(ListCellRenderer)
*/
public ListCellRenderer getListCellRenderer() {
DelegatingCellRenderer dcr = (DelegatingCellRenderer) list.
getCellRenderer();
return dcr.getFallbackCellRenderer();
}
/**
* Returns the selected value, or <code>null</code> if nothing is selected.
*
* @return The selected value.
*/
public Completion getSelection() {
return isShowing() ? (Completion) list.getSelectedValue() : lastSelection;
}
/**
* Inserts the currently selected completion.
*
* @see #getSelection()
*/
private void insertSelectedCompletion() {
Completion comp = getSelection();
ac.insertCompletion(comp);
}
public void installComp(FormulaPane.VariableTreeAndDescriptionArea component) {
this.component = component;
}
private void refreshInstallComp() {
component.refreshText(getSelection().getReplacementText());
}
/**
* Registers keyboard actions to listen for in the text component and
* intercept.
*
* @see #uninstallKeyBindings()
*/
private void installKeyBindings() {
if (AutoCompletion.isDebug()) {
FineLoggerFactory.getLogger().debug("PopupWindow: Installing keybindings");
}
if (escapeKap == null) { // Lazily create actions.
createKeyActionPairs();
}
JTextComponent comp = ac.getTextComponent();
InputMap im = comp.getInputMap();
ActionMap am = comp.getActionMap();
replaceAction(im, am, KeyEvent.VK_ESCAPE, escapeKap, oldEscape);
if (AutoCompletion.isDebug() && oldEscape.action == escapeKap.action) {
Thread.dumpStack();
}
replaceAction(im, am, KeyEvent.VK_UP, upKap, oldUp);
replaceAction(im, am, KeyEvent.VK_LEFT, leftKap, oldLeft);
replaceAction(im, am, KeyEvent.VK_DOWN, downKap, oldDown);
replaceAction(im, am, KeyEvent.VK_RIGHT, rightKap, oldRight);
replaceAction(im, am, KeyEvent.VK_ENTER, enterKap, oldEnter);
replaceAction(im, am, KeyEvent.VK_TAB, tabKap, oldTab);
replaceAction(im, am, KeyEvent.VK_HOME, homeKap, oldHome);
replaceAction(im, am, KeyEvent.VK_END, endKap, oldEnd);
replaceAction(im, am, KeyEvent.VK_PAGE_UP, pageUpKap, oldPageUp);
replaceAction(im, am, KeyEvent.VK_PAGE_DOWN, pageDownKap, oldPageDown);
// Make Ctrl+C copy from description window. This isn't done
// automagically because the desc. window is not focusable, and copying
// from text components can only be done from focused components.
KeyStroke ks = getCopyKeyStroke();
oldCtrlC.key = im.get(ks);
im.put(ks, ctrlCKap.key);
oldCtrlC.action = am.get(ctrlCKap.key);
am.put(ctrlCKap.key, ctrlCKap.action);
comp.addCaretListener(this);
}
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2 && e.getButton() == 1) {
insertSelectedCompletion();
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
refreshInstallComp();
}
public void mouseReleased(MouseEvent e) {
}
/**
* Positions the description window relative to the completion choices
* window. We assume there is room on one side of the other for this
* entire window to fit.
*/
private void positionDescWindow() {
boolean showDescWindow = descWindow != null && ac.isShowDescWindow();
if (!showDescWindow) {
return;
}
// Don't use getLocationOnScreen() as this throws an exception if
// window isn't visible yet, but getLocation() doesn't, and is in
// screen coordinates!
Point p = getLocation();
Rectangle screenBounds = Util.getScreenBoundsForPoint(p.x, p.y);
//Dimension screenSize = getToolkit().getScreenSize();
//int totalH = Math.max(getHeight(), descWindow.getHeight());
// Try to position to the right first (LTR)
int x;
if (ac.getTextComponentOrientation().isLeftToRight()) {
x = getX() + getWidth() + DIS;
if (x + descWindow.getWidth() > screenBounds.x + screenBounds.width) { // doesn't fit
x = getX() - DIS - descWindow.getWidth();
}
} else { // RTL
x = getX() - DIS - descWindow.getWidth();
if (x < screenBounds.x) { // Doesn't fit
x = getX() + getWidth() + DIS;
}
}
int y = getY();
if (aboveCaret) {
y = y + getHeight() - descWindow.getHeight();
}
if (x != descWindow.getX() || y != descWindow.getY()) {
descWindow.setLocation(x, y);
}
}
/**
* "Puts back" the original key/Action pair for a keystroke. This is used
* when this popup is hidden.
*
* @param im The input map.
* @param am The action map.
* @param key The keystroke whose key/Action pair to change.
* @param kap The (original) key/Action pair.
* @see #replaceAction(InputMap, ActionMap, int, KeyActionPair, KeyActionPair)
*/
private void putBackAction(InputMap im, ActionMap am, int key,
KeyActionPair kap) {
KeyStroke ks = KeyStroke.getKeyStroke(key, 0);
am.put(im.get(ks), kap.action); // Original action for the "new" key
im.put(ks, kap.key); // Original key for the keystroke.
}
/**
* Replaces a key/Action pair in an InputMap and ActionMap with a new
* pair.
*
* @param im The input map.
* @param am The action map.
* @param key The keystroke whose information to replace.
* @param kap The new key/Action pair for <code>key</code>.
* @param old A buffer in which to place the old key/Action pair.
* @see #putBackAction(InputMap, ActionMap, int, KeyActionPair)
*/
private void replaceAction(InputMap im, ActionMap am, int key,
KeyActionPair kap, KeyActionPair old) {
KeyStroke ks = KeyStroke.getKeyStroke(key, 0);
old.key = im.get(ks);
im.put(ks, kap.key);
old.action = am.get(kap.key);
am.put(kap.key, kap.action);
}
/**
* Selects the first item in the completion list.
*
* @see #selectLastItem()
*/
private void selectFirstItem() {
if (model.getSize() > 0) {
list.setSelectedIndex(0);
list.ensureIndexIsVisible(0);
}
}
/**
* Selects the last item in the completion list.
*
* @see #selectFirstItem()
*/
private void selectLastItem() {
int index = model.getSize() - 1;
if (index > -1) {
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
}
/**
* Selects the next item in the completion list.
*
* @see #selectPreviousItem()
*/
private void selectNextItem() {
int index = list.getSelectedIndex();
if (index > -1) {
index = (index + 1) % model.getSize();
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
}
/**
* Selects the completion item one "page down" from the currently selected
* one.
*
* @see #selectPageUpItem()
*/
private void selectPageDownItem() {
int visibleRowCount = list.getVisibleRowCount();
int i = Math.min(list.getModel().getSize() - 1,
list.getSelectedIndex() + visibleRowCount);
list.setSelectedIndex(i);
list.ensureIndexIsVisible(i);
}
/**
* Selects the completion item one "page up" from the currently selected
* one.
*
* @see #selectPageDownItem()
*/
private void selectPageUpItem() {
int visibleRowCount = list.getVisibleRowCount();
int i = Math.max(0, list.getSelectedIndex() - visibleRowCount);
list.setSelectedIndex(i);
list.ensureIndexIsVisible(i);
}
/**
* Selects the previous item in the completion list.
*
* @see #selectNextItem()
*/
private void selectPreviousItem() {
int index = list.getSelectedIndex();
switch (index) {
case 0:
index = list.getModel().getSize() - 1;
break;
case -1: // Check for an empty list (would be an error)
index = list.getModel().getSize() - 1;
if (index == -1) {
return;
}
break;
default:
index = index - 1;
break;
}
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
/**
* Sets the completions to display in the choices list. The first
* completion is selected.
*
* @param completions The completions to display.
*/
public void setCompletions(List<Completion> completions) {
model.setContents(completions);
selectFirstItem();
}
/**
* Sets the size of the description window.
*
* @param size The new size. This cannot be <code>null</code>.
*/
public void setDescriptionWindowSize(Dimension size) {
if (descWindow != null) {
descWindow.setSize(size);
} else {
preferredDescWindowSize = size;
}
}
/**
* Sets the default list cell renderer to use when a completion provider
* does not supply its own.
*
* @param renderer The renderer to use. If this is <code>null</code>,
* a default renderer is used.
* @see #getListCellRenderer()
*/
public void setListCellRenderer(ListCellRenderer renderer) {
DelegatingCellRenderer dcr = (DelegatingCellRenderer) list.
getCellRenderer();
dcr.setFallbackCellRenderer(renderer);
}
/**
* Sets the location of this window to be "good" relative to the specified
* rectangle. That rectangle should be the location of the text
* component's caret, in screen coordinates.
*
* @param r The text component's caret position, in screen coordinates.
*/
public void setLocationRelativeTo(Rectangle r) {
// Multi-monitor support - make sure the completion window (and
// description window, if applicable) both fit in the same window in
// a multi-monitor environment. To do this, we decide which monitor
// the rectangle "r" is in, and use that one (just pick top-left corner
// as the defining point).
Rectangle screenBounds = Util.getScreenBoundsForPoint(r.x, r.y);
//Dimension screenSize = getToolkit().getScreenSize();
boolean showDescWindow = descWindow != null && ac.isShowDescWindow();
int totalH = getHeight();
if (showDescWindow) {
totalH = Math.max(totalH, descWindow.getHeight());
}
// Try putting our stuff "below" the caret first. We assume that the
// entire height of our stuff fits on the screen one way or the other.
aboveCaret = false;
int y = r.y + r.height + VERTICAL_SPACE;
if (y + totalH > screenBounds.height) {
y = r.y - VERTICAL_SPACE - getHeight();
aboveCaret = true;
}
// Get x-coordinate of completions. Try to align left edge with the
// caret first.
int x = r.x;
if (!ac.getTextComponentOrientation().isLeftToRight()) {
x -= getWidth(); // RTL => align right edge
}
if (x < screenBounds.x) {
x = screenBounds.x;
} else if (x + getWidth() > screenBounds.x + screenBounds.width) { // completions don't fit
x = screenBounds.x + screenBounds.width - getWidth();
}
setLocation(x, y);
// Position the description window, if necessary.
if (showDescWindow) {
positionDescWindow();
}
}
/**
* Toggles the visibility of this popup window.
*
* @param visible Whether this window should be visible.
*/
@Override
public void setVisible(boolean visible) {
if (visible != isVisible()) {
if (visible) {
installKeyBindings();
lastLine = ac.getLineOfCaret();
selectFirstItem();
if (descWindow == null && ac.isShowDescWindow()) {
descWindow = createDescriptionWindow();
positionDescWindow();
}
// descWindow needs a kick-start the first time it's displayed.
// Also, the newly-selected item in the choices list is
// probably different from the previous one anyway.
if (descWindow != null) {
Completion c = (Completion) list.getSelectedValue();
if (c != null) {
descWindow.setDescriptionFor(c);
}
}
} else {
uninstallKeyBindings();
}
super.setVisible(visible);
// Some languages, such as Java, can use quite a lot of memory
// when displaying hundreds of completion choices. We pro-actively
// clear our list model here to make them available for GC.
// Otherwise, they stick around, and consider the following: a
// user starts code-completion for Java 5 SDK classes, then hides
// the dialog, then changes the "class path" to use a Java 6 SDK
// instead. On pressing Ctrl+space, a new array of Completions is
// created. If this window holds on to the previous Completions,
// you're getting roughly 2x the necessary Completions in memory
// until the Completions are actually passed to this window.
if (!visible) { // Do after super.setVisible(false)
lastSelection = (Completion) list.getSelectedValue();
model.clear();
}
// Must set descWindow's visibility one way or the other each time,
// because of the way child JWindows' visibility is handled - in
// some ways it's dependent on the parent, in other ways it's not.
if (descWindow != null) {
descWindow.setVisible(visible && ac.isShowDescWindow());
}
}
}
/**
* Stops intercepting certain keystrokes from the text component.
*
* @see #installKeyBindings()
*/
private void uninstallKeyBindings() {
if (AutoCompletion.isDebug()) {
FineLoggerFactory.getLogger().debug("PopupWindow: Removing keybindings");
}
JTextComponent comp = ac.getTextComponent();
InputMap im = comp.getInputMap();
ActionMap am = comp.getActionMap();
putBackAction(im, am, KeyEvent.VK_ESCAPE, oldEscape);
putBackAction(im, am, KeyEvent.VK_UP, oldUp);
putBackAction(im, am, KeyEvent.VK_DOWN, oldDown);
putBackAction(im, am, KeyEvent.VK_LEFT, oldLeft);
putBackAction(im, am, KeyEvent.VK_RIGHT, oldRight);
putBackAction(im, am, KeyEvent.VK_ENTER, oldEnter);
putBackAction(im, am, KeyEvent.VK_TAB, oldTab);
putBackAction(im, am, KeyEvent.VK_HOME, oldHome);
putBackAction(im, am, KeyEvent.VK_END, oldEnd);
putBackAction(im, am, KeyEvent.VK_PAGE_UP, oldPageUp);
putBackAction(im, am, KeyEvent.VK_PAGE_DOWN, oldPageDown);
// Ctrl+C
KeyStroke ks = getCopyKeyStroke();
am.put(im.get(ks), oldCtrlC.action); // Original action
im.put(ks, oldCtrlC.key); // Original key
comp.removeCaretListener(this);
}
/**
* Updates the <tt>LookAndFeel</tt> of this window and the description
* window.
*/
public void updateUI() {
SwingUtilities.updateComponentTreeUI(this);
if (descWindow != null) {
descWindow.updateUI();
}
}
/**
* Called when a new item is selected in the popup list.
*
* @param e The event.
*/
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
Object value = list.getSelectedValue();
if (value != null && descWindow != null) {
descWindow.setDescriptionFor((Completion) value);
positionDescWindow();
}
}
}
class CopyAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
boolean doNormalCopy = false;
if (descWindow != null && descWindow.isVisible()) {
doNormalCopy = !descWindow.copy();
}
if (doNormalCopy) {
ac.getTextComponent().copy();
}
}
}
class DownAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
selectNextItem();
refreshInstallComp();
}
}
}
class EndAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
selectLastItem();
}
}
}
class EnterAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
insertSelectedCompletion();
refreshInstallComp();
}
}
super(parent,ac);
}
class EscapeAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
setVisible(false);
}
}
}
class HomeAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
selectFirstItem();
}
}
}
/**
* A mapping from a key (an Object) to an Action.
*/
private static class KeyActionPair {
public Object key;
public Action action;
public KeyActionPair() {
}
public KeyActionPair(Object key, Action a) {
this.key = key;
this.action = a;
}
}
class LeftAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
JTextComponent comp = ac.getTextComponent();
Caret c = comp.getCaret();
int dot = c.getDot();
if (dot > 0) {
c.setDot(--dot);
// Ensure moving left hasn't moved us up a line, thus
// hiding the popup window.
if (comp.isVisible()) {
if (lastLine != -1) {
doAutocomplete();
}
}
}
}
}
}
class PageDownAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
selectPageDownItem();
}
}
}
class PageUpAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
selectPageUpItem();
}
}
}
/**
* The actual list of completion choices in this popup window.
*/
private class PopupList extends JList {
public PopupList(CompletionListModel model) {
super(model);
}
@Override
public void setUI(ListUI ui) {
if (Util.getUseSubstanceRenderers() &&
SUBSTANCE_LIST_UI.equals(ui.getClass().getName())) {
// Substance requires its special ListUI be installed for
// its renderers to actually render (!), but long completion
// lists (e.g. PHPCompletionProvider in RSTALanguageSupport)
// will simply populate too slowly on initial display (when
// calculating preferred size of all items), so in this case
// we give a prototype cell value.
CompletionProvider p = ac.getCompletionProvider();
BasicCompletion bc = new BasicCompletion(p, "Hello world");
setPrototypeCellValue(bc);
} else {
// Our custom UI that is faster for long HTML completion lists.
ui = new FastListUI();
setPrototypeCellValue(null);
}
super.setUI(ui);
}
}
class RightAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
JTextComponent comp = ac.getTextComponent();
Caret c = comp.getCaret();
int dot = c.getDot();
if (dot < comp.getDocument().getLength()) {
c.setDot(++dot);
// Ensure moving right hasn't moved us up a line, thus
// hiding the popup window.
if (comp.isVisible()) {
if (lastLine != -1) {
doAutocomplete();
}
}
}
}
}
}
class UpAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
selectPreviousItem();
refreshInstallComp();
}
}
}
}

1241
designer-base/src/main/java/com/fr/design/gui/autocomplete/FormulaPaneAutoCompletion.java

File diff suppressed because it is too large Load Diff

16
designer-base/src/main/java/com/fr/design/gui/autocomplete/JSAutoCompletePopupWindow.java

@ -0,0 +1,16 @@
package com.fr.design.gui.autocomplete;
import java.awt.Window;
public class JSAutoCompletePopupWindow extends AutoCompleteWithExtraRefreshPopupWindow {
/**
* Constructor.
*
* @param parent The parent window (hosting the text component).
* @param ac The auto-completion instance.
*/
public JSAutoCompletePopupWindow(Window parent, AutoCompletion ac) {
super(parent, ac);
}
}

31
designer-base/src/main/java/com/fr/design/gui/autocomplete/JSImplPaneAutoCompletion.java

@ -0,0 +1,31 @@
package com.fr.design.gui.autocomplete;
public class JSImplPaneAutoCompletion extends AutoCompletionWithExtraRefresh{
/**
* Constructor.
*
* @param provider The completion provider. This cannot be
* <code>null</code>.
*/
public JSImplPaneAutoCompletion(CompletionProvider provider) {
super(provider);
}
@Override
protected AutoCompleteWithExtraRefreshPopupWindow createAutoCompletePopupWindow() {
JSAutoCompletePopupWindow popupWindow = new JSAutoCompletePopupWindow(getParentWindow(),this);
popupWindow.applyComponentOrientation(
getTextComponentOrientation());
if (getCellRender() != null) {
popupWindow.setListCellRenderer(getCellRender());
}
if (getPreferredChoicesWindowSize() != null) {
popupWindow.setSize(getPreferredChoicesWindowSize());
}
if (getPreferredDescWindowSize() != null) {
popupWindow.setDescriptionWindowSize(
getPreferredDescWindowSize());
}
return popupWindow;
}
}

78
designer-base/src/main/java/com/fr/design/gui/ilable/UIAutoChangeLineLabel.java

@ -0,0 +1,78 @@
package com.fr.design.gui.ilable;
import javax.swing.JLabel;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.util.ArrayList;
import java.util.List;
public class UIAutoChangeLineLabel extends JLabel {
private final String text;
private final int width;
public UIAutoChangeLineLabel(String text, int width) {
super(text);
this.text = text;
this.width = width;
}
@Override
public void doLayout() {
super.doLayout();
this.setText(wrapperHtmlText());
}
private String wrapperHtmlText() {
List<String> stringList = autoChangeLine(this.getWidth());
StringBuilder builder = new StringBuilder("<html>");
for (String s : stringList) {
//用THML标签进行拼接,以实现自动换行
builder.append(s).append("<br/>");
}
builder.append("</html>");
return builder.toString();
}
private List<String> autoChangeLine(int width) {
List<String> result = new ArrayList<>();
if (width <= 0) {
result.add(this.text);
} else {
char[] chars = this.text.toCharArray();
//获取字体计算大小
FontMetrics fontMetrics = this.getFontMetrics(this.getFont());
int start = 0;
int len = 0;
while (start + len < this.text.length()) {
while (true) {
len++;
if (start + len > this.text.length())
break;
if (fontMetrics.charsWidth(chars, start, len)
> width) {
break;
}
}
result.add(String.copyValueOf(chars, start, len - 1));
start = start + len - 1;
len = 0;
}
if (this.text.length() - start > 0) {
result.add(String.copyValueOf(chars, start, this.text.length() - start));
}
}
return result;
}
@Override
public Dimension getPreferredSize() {
Dimension preferredSize = super.getPreferredSize();
List<String> stringList = autoChangeLine(width);
FontMetrics fontMetrics = this.getFontMetrics(this.getFont());
return new Dimension(preferredSize.width, fontMetrics.getHeight() * stringList.size());
}
}

13
designer-base/src/main/java/com/fr/design/gui/style/BorderPane.java

@ -4,7 +4,6 @@ package com.fr.design.gui.style;
* Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved.
*/
import com.fr.base.BaseUtils;
import com.fr.base.CellBorderStyle;
import com.fr.base.Style;
import com.fr.design.constants.LayoutConstants;
@ -17,8 +16,8 @@ import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.style.color.NewColorSelectBox;
import com.fr.general.IOUtils;
import com.fr.design.utils.gui.AdjustWorkBookDefaultStyleUtils;
import com.fr.general.IOUtils;
import com.fr.stable.Constants;
import com.fr.stable.CoreConstants;
@ -206,6 +205,8 @@ public class BorderPane extends AbstractBasicStylePane implements GlobalNameObse
}
public void populateLineStyleAndColor(CellBorderStyle cellBorderStyle, boolean onlyInspectTop) {
resetLineStyleAndColorSetting();
if (cellBorderStyle.getTopStyle() != Constants.LINE_NONE) {
this.currentLineCombo.setSelectedLineStyle(cellBorderStyle.getTopStyle());
this.currentLineColorPane.setSelectObject(cellBorderStyle.getTopColor());
@ -225,9 +226,6 @@ public class BorderPane extends AbstractBasicStylePane implements GlobalNameObse
} else if (cellBorderStyle.getHorizontalStyle() != Constants.LINE_NONE) {
this.currentLineCombo.setSelectedLineStyle(cellBorderStyle.getHorizontalStyle());
this.currentLineColorPane.setSelectObject(cellBorderStyle.getHorizontalColor());
} else {
this.currentLineCombo.setSelectedLineStyle(Constants.LINE_NONE);
this.currentLineColorPane.setSelectObject(Color.BLACK);
}
}
@ -236,6 +234,11 @@ public class BorderPane extends AbstractBasicStylePane implements GlobalNameObse
}
}
private void resetLineStyleAndColorSetting() {
this.currentLineCombo.setSelectedLineStyle(Constants.LINE_NONE);
this.currentLineColorPane.setSelectObject(null);
}
@Override
public Style update(Style style) {

167
designer-base/src/main/java/com/fr/design/javascript/JSContentPane.java

@ -4,7 +4,9 @@ import com.fr.design.DesignerEnvManager;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.KeyWords;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.autocomplete.AutoCompletion;
import com.fr.design.gui.autocomplete.BasicCompletion;
import com.fr.design.gui.autocomplete.CompletionProvider;
@ -15,31 +17,145 @@ import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxTextArea;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants;
import com.fr.design.javascript.beautify.JavaScriptFormatHelper;
import com.fr.design.javascript.jsapi.JSImplPopulateAction;
import com.fr.design.javascript.jsapi.JSImplUpdateAction;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.general.IOUtils;
import com.fr.js.JavaScriptImpl;
import javax.swing.*;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
public class JSContentPane extends BasicPane {
private RSyntaxTextArea contentTextArea;
private UILabel funNameLabel;
protected RSyntaxTextArea contentTextArea;
private UILabel funNameLabel = new UILabel();
private AutoCompletion ac;
private static final Dimension FUNCTION_NAME_LABEL_SIZE = new Dimension(300, 80);
private String[] defaultArgs;
private int titleWidth = 180;
private JPanel labelPane = new JPanel(new BorderLayout(6, 4));;
private NewJavaScriptImplPane newJavaScriptImplPane = null;
private JavaScriptImpl javaScript;
private JSImplUpdateAction jsImplUpdateAction;
private JSImplPopulateAction jsImplPopulateAction;
private boolean modal;
BasicDialog advancedEditorDialog ;
public JSContentPane(){}
public JSContentPane(String[] args) {
defaultArgs = args;
this.setLayout(FRGUIPaneFactory.createBorderLayout());
funNameLabel = new UILabel();
this.setFunctionTitle(args);
initFunctionTitle(args);
JPanel jsParaPane = createJSParaPane();
addNewPaneLabel();
this.add(jsParaPane, BorderLayout.NORTH);
UIScrollPane sp = createContentTextAreaPanel();
initContentTextAreaListener();
this.add(sp, BorderLayout.CENTER);
UILabel funNameLabel2 = new UILabel();
funNameLabel2.setText("}");
this.add(funNameLabel2, BorderLayout.SOUTH);
}
public JSContentPane(String[] args,boolean modal) {
this(args);
this.modal = modal;
}
public void setJsImplUpdateAction(JSImplUpdateAction jsImplUpdateAction){
this.jsImplUpdateAction = jsImplUpdateAction;
}
public void setJsImplPopulateAction(JSImplPopulateAction jsImplPopulateAction){
this.jsImplPopulateAction = jsImplPopulateAction;
}
public void updateJSImpl(JavaScriptImpl javaScript){
this.javaScript = javaScript;
}
private void addNewPaneLabel(){
UILabel advancedEditorLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Advanced_Editor"), SwingConstants.LEFT);
advancedEditorLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
advancedEditorLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if(newJavaScriptImplPane == null){
newJavaScriptImplPane = new NewJavaScriptImplPane(defaultArgs);
}
jsImplUpdateAction.update(javaScript);
newJavaScriptImplPane.populate(javaScript);
if(advancedEditorDialog == null || !advancedEditorDialog.isVisible()) {
advancedEditorDialog = newJavaScriptImplPane.showWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() {
@Override
public void doOk() {
if (javaScript != null) {
newJavaScriptImplPane.updateBean(javaScript);
jsImplPopulateAction.populate(javaScript);
}
}
@Override
public void doCancel() {
super.doCancel();
}
});
advancedEditorDialog.setModal(modal);
advancedEditorDialog.setResizable(true);
advancedEditorDialog.pack();
advancedEditorDialog.setVisible(true);
}
advancedEditorDialog.requestFocus();
}
});
labelPane.add(advancedEditorLabel,BorderLayout.CENTER);
}
protected UIScrollPane createContentTextAreaPanel(){
contentTextArea = new RSyntaxTextArea();
contentTextArea.setCloseCurlyBraces(true);
contentTextArea.setLineWrap(true);
contentTextArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT);
contentTextArea.setCodeFoldingEnabled(true);
contentTextArea.setAntiAliasingEnabled(true);
return new UIScrollPane(contentTextArea);
}
private void initContentTextAreaListener(){
contentTextArea.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
// 获得焦点时 安装
installAutoCompletion();
}
@Override
public void focusLost(FocusEvent e) {
// 失去焦点时 卸载
uninstallAutoCompletion();
}
});
}
protected JPanel createJSParaPane(){
UILabel label = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Format_JavaScript"), IOUtils.readIcon("com/fr/design/images/edit/format.png"), SwingConstants.LEFT);
label.setCursor(new Cursor(Cursor.HAND_CURSOR));
label.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Format_JavaScript"));
@ -65,43 +181,20 @@ public class JSContentPane extends BasicPane {
}
});
//REPORT-10533 用户参数多达25个,导致JS没地方写,增加滚动条显示
labelPane.add(label,BorderLayout.EAST);
JPanel jsParaPane = new JPanel(new BorderLayout(4, 4));
jsParaPane.setPreferredSize(new Dimension(300, 80));
UIScrollPane scrollPane = new UIScrollPane(funNameLabel);
scrollPane.setPreferredSize(FUNCTION_NAME_LABEL_SIZE);
scrollPane.setBorder(new UIRoundedBorder(UIConstants.TITLED_BORDER_COLOR, 1, UIConstants.ARC));
jsParaPane.add(scrollPane, BorderLayout.WEST);
jsParaPane.add(label, BorderLayout.EAST);
this.add(jsParaPane, BorderLayout.NORTH);
contentTextArea = new RSyntaxTextArea();
contentTextArea.setCloseCurlyBraces(true);
contentTextArea.setLineWrap(true);
contentTextArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT);
contentTextArea.setCodeFoldingEnabled(true);
contentTextArea.setAntiAliasingEnabled(true);
UIScrollPane sp = new UIScrollPane(contentTextArea);
this.add(sp, BorderLayout.CENTER);
contentTextArea.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
// 获得焦点时 安装
installAutoCompletion();
}
@Override
public void focusLost(FocusEvent e) {
// 失去焦点时 卸载
uninstallAutoCompletion();
}
});
jsParaPane.add(labelPane, BorderLayout.EAST);
return jsParaPane;
}
UILabel funNameLabel2 = new UILabel();
funNameLabel2.setText("}");
this.add(funNameLabel2, BorderLayout.SOUTH);
protected void initFunctionTitle(String[] args){
funNameLabel = new UILabel();
this.setFunctionTitle(args);
}
private KeyStroke convert2KeyStroke(String ks) {

858
designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java

@ -0,0 +1,858 @@
package com.fr.design.javascript;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.autocomplete.AutoCompleteExtraRefreshComponent;
import com.fr.design.gui.autocomplete.BasicCompletion;
import com.fr.design.gui.autocomplete.CompletionCellRenderer;
import com.fr.design.gui.autocomplete.CompletionProvider;
import com.fr.design.gui.autocomplete.DefaultCompletionProvider;
import com.fr.design.gui.autocomplete.JSImplPaneAutoCompletion;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextarea.UITextArea;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.javascript.jsapi.JSAPITreeHelper;
import com.fr.design.javascript.jsapi.JSAPIUserObject;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.general.CloudCenter;
import com.fr.general.ComparatorUtils;
import com.fr.general.http.HttpToolbox;
import com.fr.json.JSONArray;
import com.fr.json.JSONException;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class JSContentWithDescriptionPane extends JSContentPane implements KeyListener {
//搜索关键词输入框
private UITextField keyWordTextField = new UITextField(16);
//搜索出的提示列表
private JList tipsList;
private DefaultListModel tipsListModel = new DefaultListModel();
private JList interfaceNameList;
private DefaultListModel interfaceNameModel;
private JTree moduleTree;
private DefaultCompletionProvider completionProvider;
private JSImplPaneAutoCompletion autoCompletion;
//函数说明文本框
private UITextArea descriptionTextArea;
private JPopupMenu popupMenu;
private InterfaceAndDescriptionPanel interfaceAndDescriptionPanel;
private JList helpDOCList;
private int ifHasBeenWriten = 0;
private int currentPosition = 0;
private int beginPosition = 0;
private int insertPosition = 0;
private static final String SEPARATOR = "_";
private static final int KEY_10 = 10;
//上下左右
private static final int KEY_37 = 37;
private static final int KEY_38 = 38;
private static final int KEY_39 = 39;
private static final int KEY_40 = 40;
private static final String URL_FOR_TEST_NETWORK = "https://www.baidu.com";
private static final String DOCUMENT_SEARCH_URL = CloudCenter.getInstance().acquireUrlByKind("af.doc_search");
private String currentValue;
public JSContentWithDescriptionPane(String[] args) {
this.setLayout(new BorderLayout());
//===============================
this.initFunctionTitle(args);
JPanel jsParaAndSearchPane = new JPanel(new BorderLayout());
//js函数声明面板
JPanel jsParaPane = createJSParaPane();
jsParaPane.setPreferredSize(new Dimension(650, 80));
//右上角的搜索提示面板
JPanel tipsPane = createTipsPane();
jsParaAndSearchPane.add(jsParaPane, BorderLayout.CENTER);
jsParaAndSearchPane.add(tipsPane, BorderLayout.EAST);
initPopTips();
//js文本编辑面板
UIScrollPane contentTextAreaPanel = createContentTextAreaPanel();
initContextAreaListener();
contentTextAreaPanel.setPreferredSize(new Dimension(850, 250));
//js函数结束标签
UILabel endBracketsLabel = new UILabel();
endBracketsLabel.setText("}");
//结尾括号和复用函数按钮面板
JPanel endBracketsPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
endBracketsPanel.add(endBracketsLabel, BorderLayout.WEST);
JPanel northPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
northPanel.add(jsParaAndSearchPane, BorderLayout.NORTH);
northPanel.add(contentTextAreaPanel, BorderLayout.CENTER);
northPanel.add(endBracketsPanel, BorderLayout.SOUTH);
//主编辑框,也就是面板的正中间部分
this.add(northPanel, BorderLayout.CENTER);
//函数分类和函数说明面板==================================
JPanel functionNameAndDescriptionPanel = createInterfaceAndDescriptionPanel();
functionNameAndDescriptionPanel.setPreferredSize(new Dimension(880, 220));
this.add(functionNameAndDescriptionPanel, BorderLayout.SOUTH);
}
private void initContextAreaListener() {
contentTextArea.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
if ((e.getKeyChar() >= 'A' && e.getKeyChar() <= 'z') || e.getKeyChar() == '_') {
if (autoCompletion != null) {
autoCompletion.doCompletion();
}
}
}
@Override
public void keyReleased(KeyEvent e) {
contentTextArea.setForeground(Color.black);
}
});
contentTextArea.addKeyListener(this);
contentTextArea.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
if (autoCompletion == null) {
installAutoCompletion();
}
}
@Override
public void focusLost(FocusEvent e) {
uninstallAutoCompletion();
}
});
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (ifHasBeenWriten == 0) {
this.contentTextArea.setText(StringUtils.EMPTY);
}
}
@Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KEY_38 || key == KEY_40 || key == KEY_37 || key == KEY_39 || key == KEY_10) //如果是删除符号 ,为了可读性 没有和其他按键的程序相融合
{
currentPosition = contentTextArea.getCaretPosition();
insertPosition = currentPosition;
beginPosition = getBeginPosition();
} else {
if (contentTextArea.getText().trim().length() == 0) {
insertPosition = 0;
} else {
contentTextArea.setForeground(Color.black);
currentPosition = contentTextArea.getCaretPosition();
beginPosition = getBeginPosition();
insertPosition = beginPosition;
ifHasBeenWriten = 1;
}
}
}
private int getBeginPosition() {
int i = currentPosition;
String textArea = contentTextArea.getText();
for (; i > 0; i--) {
String tested = textArea.substring(i - 1, i).toUpperCase();
char[] testedChar = tested.toCharArray();
if (isChar(testedChar[0]) || isNum(testedChar[0])) {
continue;
} else {
break;
}
}
return i;
}
private static boolean isNum(char tested) {
return tested >= '0' && tested <= '9';
}
private boolean isChar(char tested) {
return tested >= 'A' && tested <= 'Z' || tested >= 'a' && tested < 'z';
}
public class InterfaceAndDescriptionPanel extends JPanel implements AutoCompleteExtraRefreshComponent {
@Override
public void refresh(String replacementText) {
fixInterfaceNameList(replacementText);
}
}
private void fixInterfaceNameList(String interfaceName) {
DefaultTreeModel defaultTreeModel = (DefaultTreeModel) moduleTree.getModel();
TreeNode root = (TreeNode) defaultTreeModel.getRoot();
String directCategory = JSAPITreeHelper.getDirectCategory(interfaceName);
if (directCategory == null) {
return;
}
setModuleTreeSelection(root, directCategory, defaultTreeModel);
interfaceNameModel = (DefaultListModel) interfaceNameList.getModel();
interfaceNameModel.clear();
List<String> interfaceNames = JSAPITreeHelper.getNames(directCategory);
int index = 0;
for (int i = 0; i < interfaceNames.size(); i++) {
interfaceNameModel.addElement(interfaceNames.get(i));
if (StringUtils.equals(interfaceNames.get(i), interfaceName)) {
index = i;
}
}
interfaceNameList.setSelectedIndex(index);
interfaceNameList.ensureIndexIsVisible(index);
}
private boolean setModuleTreeSelection(TreeNode node, String directCategory, DefaultTreeModel treeModel) {
DefaultMutableTreeNode defaultMutableTreeNode = (DefaultMutableTreeNode) node;
Object userObject = defaultMutableTreeNode.getUserObject();
if (userObject instanceof JSAPIUserObject) {
String value = ((JSAPIUserObject) userObject).getValue();
if (StringUtils.equals(value, directCategory)) {
moduleTree.setSelectionPath(new TreePath(treeModel.getPathToRoot(node)));
return true;
}
return false;
}
for (int i = 0; i < node.getChildCount(); i++) {
if (setModuleTreeSelection(node.getChildAt(i), directCategory, treeModel)) {
return true;
}
}
return false;
}
private JPanel createInterfaceAndDescriptionPanel() {
interfaceAndDescriptionPanel = new InterfaceAndDescriptionPanel();
interfaceAndDescriptionPanel.setLayout(new BorderLayout(4, 4));
JPanel interfacePanel = new JPanel(new BorderLayout(4, 4));
interfaceAndDescriptionPanel.add(interfacePanel, BorderLayout.WEST);
JPanel descriptionAndDocumentPanel = new JPanel(new BorderLayout(4, 4));
//函数说明和帮助文档框
initDescriptionArea(descriptionAndDocumentPanel);
//模块和接口面板
initInterfaceModuleTree(interfacePanel);
initInterfaceNameList(interfacePanel);
initHelpDocumentPane(descriptionAndDocumentPanel);
interfaceAndDescriptionPanel.add(descriptionAndDocumentPanel, BorderLayout.CENTER);
return interfaceAndDescriptionPanel;
}
private void doHelpDocumentSearch() {
Object value = interfaceNameList.getSelectedValue();
if (value != null) {
String url = DOCUMENT_SEARCH_URL + value.toString();
try {
String result = HttpToolbox.get(url);
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonArray = jsonObject.optJSONArray("list");
if (jsonArray != null) {
DefaultListModel helpDOCModel = (DefaultListModel) helpDOCList.getModel();
helpDOCModel.clear();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject resultJSONObject = jsonArray.optJSONObject(i);
String docURL = resultJSONObject.optString("url");
String name = resultJSONObject.optString("title").trim();
HelpDocument helpDocument = new HelpDocument(docURL, name);
helpDOCModel.addElement(helpDocument);
}
}
} catch (JSONException e) {
FineLoggerFactory.getLogger().debug(e.getMessage(), e);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
private void initHelpDocumentPane(JPanel descriptionAndDocumentPanel) {
UIScrollPane helpDOCScrollPane;
if (isNetworkOk()) {
helpDOCList = new JList(new DefaultListModel());
initHelpDOCListRender();
initHelpDOCListListener();
helpDOCScrollPane = new UIScrollPane(helpDOCList);
doHelpDocumentSearch();
} else {
UILabel label1 = new UILabel(Toolkit.i18nText("Fine-Design_Net_Connect_Failed"), 0);
label1.setPreferredSize(new Dimension(180, 20));
UILabel label2 = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Reload"), 0);
label2.setPreferredSize(new Dimension(180, 20));
label2.setForeground(Color.blue);
JPanel labelPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, 0, 0, 0);
labelPane.setBackground(Color.WHITE);
labelPane.add(label1);
labelPane.add(label2);
JPanel containerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
containerPanel.add(labelPane, BorderLayout.CENTER);
helpDOCScrollPane = new UIScrollPane(containerPanel);
label2.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
descriptionAndDocumentPanel.removeAll();
initHelpDocumentPane(descriptionAndDocumentPanel);
}
});
}
helpDOCScrollPane.setPreferredSize(new Dimension(200, 200));
helpDOCScrollPane.setBorder(null);
descriptionAndDocumentPanel.add(this.createNamePane(Toolkit.i18nText("Fine-Design_Relevant_Cases"), helpDOCScrollPane), BorderLayout.EAST);
}
private void initHelpDOCListListener() {
helpDOCList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
Object value = helpDOCList.getSelectedValue();
if (value instanceof HelpDocument) {
String url = ((HelpDocument) value).getDocumentUrl();
try {
Desktop.getDesktop().browse(new URI(url));
} catch (IOException ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
} catch (URISyntaxException ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
}
}
}
}
});
}
private void initHelpDOCListRender() {
helpDOCList.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof HelpDocument) {
this.setText(((HelpDocument) value).getName());
this.setForeground(Color.BLUE);
}
return this;
}
});
}
private static boolean isNetworkOk() {
try {
HttpToolbox.get(URL_FOR_TEST_NETWORK);
return true;
} catch (Exception ignore) {
// 网络异常
return false;
}
}
private static class HelpDocument {
private String documentUrl;
private String name;
public HelpDocument(String documentUrl, String name) {
this.documentUrl = documentUrl;
this.name = name;
}
public String getDocumentUrl() {
return documentUrl;
}
public String getName() {
return name;
}
}
private void initDescriptionArea(JPanel descriptionPanel) {
descriptionTextArea = new UITextArea();
UIScrollPane descriptionScrollPane = new UIScrollPane(descriptionTextArea);
descriptionScrollPane.setPreferredSize(new Dimension(300, 200));
descriptionPanel.add(this.createNamePane(Toolkit.i18nText("Fine-Design_Interface_Description"), descriptionScrollPane), BorderLayout.CENTER);
descriptionTextArea.setBackground(Color.white);
descriptionTextArea.setLineWrap(true);
descriptionTextArea.setWrapStyleWord(true);
descriptionTextArea.setEditable(false);
}
private void installAutoCompletion() {
CompletionProvider provider = createCompletionProvider();
autoCompletion = new JSImplPaneAutoCompletion(provider);
autoCompletion.setListCellRenderer(new CompletionCellRenderer());
autoCompletion.install(contentTextArea);
autoCompletion.installExtraRefreshComponent(interfaceAndDescriptionPanel);
}
private void uninstallAutoCompletion() {
if (autoCompletion != null) {
autoCompletion.uninstall();
autoCompletion = null;
}
}
private CompletionProvider createCompletionProvider() {
if (completionProvider == null) {
completionProvider = new DefaultCompletionProvider();
for (String name : JSAPITreeHelper.getAllNames()) {
completionProvider.addCompletion(new BasicCompletion(completionProvider, name));
}
}
return completionProvider;
}
private void initInterfaceModuleTree(JPanel interfacePanel) {
moduleTree = new JTree();
UIScrollPane moduleTreePane = new UIScrollPane(moduleTree);
moduleTreePane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
interfacePanel.add(this.createNamePane(Toolkit.i18nText("Fine-Design_Module"), moduleTreePane), BorderLayout.WEST);
moduleTreePane.setPreferredSize(new Dimension(180, 200));
moduleTree.setRootVisible(false);
moduleTree.setShowsRootHandles(true);
moduleTree.setCellRenderer(moduleTreeCellRender);
DefaultTreeModel moduleTreeModel = (DefaultTreeModel) moduleTree.getModel();
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) moduleTreeModel.getRoot();
rootNode.removeAllChildren();
JSAPITreeHelper.createJSAPITree(rootNode);
moduleTreeModel.reload();
initModuleTreeSelectionListener();
}
private void initModuleTreeSelectionListener() {
moduleTree.addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode selectedTreeNode = (DefaultMutableTreeNode) moduleTree.getLastSelectedPathComponent();
Object selectedValue = selectedTreeNode.getUserObject();
if (null == selectedValue) {
return;
}
if (selectedValue instanceof JSAPIUserObject) {
interfaceNameModel = (DefaultListModel) interfaceNameList.getModel();
interfaceNameModel.clear();
String text = ((JSAPIUserObject) selectedValue).getValue();
List<String> allInterfaceNames = JSAPITreeHelper.getNames(text);
for (String interfaceName : allInterfaceNames) {
interfaceNameModel.addElement(interfaceName);
}
if (interfaceNameModel.size() > 0) {
interfaceNameList.setSelectedIndex(0);
setDescription(interfaceNameList.getSelectedValue().toString());
interfaceNameList.ensureIndexIsVisible(0);
}
}
}
});
}
private DefaultTreeCellRenderer moduleTreeCellRender = new DefaultTreeCellRenderer() {
public Component getTreeCellRendererComponent(JTree tree,
Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, selected,
expanded, leaf, row, hasFocus);
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value;
Object userObj = treeNode.getUserObject();
if (userObj instanceof JSAPIUserObject) {
this.setText(((JSAPIUserObject) userObj).getDisplayText());
this.setIcon(null);
}
return this;
}
};
private void initInterfaceNameList(JPanel interfacePanel) {
interfaceNameList = new JList(new DefaultListModel());
UIScrollPane interfaceNamePanelScrollPane = new UIScrollPane(interfaceNameList);
interfaceNamePanelScrollPane.setPreferredSize(new Dimension(180, 200));
interfacePanel.add(
this.createNamePane(Toolkit.i18nText("Fine-Design_Interface") + ":", interfaceNamePanelScrollPane),
BorderLayout.CENTER);
interfaceNamePanelScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
initInterfaceNameModule();
initInterfaceNameListSelectionListener();
initInterfaceNameListMouseListener();
}
private void initInterfaceNameModule() {
moduleTree.setSelectionPath(moduleTree.getPathForRow(0));
}
private void setDescription(String interfaceName) {
StringBuilder il8Key = new StringBuilder();
moduleTree.getSelectionPath().getPath();
Object obj = moduleTree.getSelectionPath().getPath()[moduleTree.getSelectionPath().getPath().length - 1];
Object userObject = ((DefaultMutableTreeNode) obj).getUserObject();
if (userObject instanceof JSAPIUserObject) {
il8Key.append(JSAPITreeHelper.getDirectCategory(interfaceName));
}
interfaceName = interfaceName.toUpperCase();
if (!interfaceName.startsWith(SEPARATOR)) {
interfaceName = SEPARATOR + interfaceName;
}
il8Key.append(interfaceName);
descriptionTextArea.setText(Toolkit.i18nText(il8Key.toString()));
descriptionTextArea.moveCaretPosition(0);
}
private void initInterfaceNameListSelectionListener() {
interfaceNameList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
Object selectedValue = interfaceNameList.getSelectedValue();
if (selectedValue == null) {
return;
}
String interfaceName = selectedValue.toString();
if (!StringUtils.equals(interfaceName, currentValue)) {
setDescription(interfaceName);
doHelpDocumentSearch();
currentValue = interfaceName;
}
}
});
}
private void initInterfaceNameListMouseListener() {
interfaceNameList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
if (evt.getClickCount() >= 2) {
Object selectedValue = interfaceNameList.getSelectedValue();
String interfaceName = selectedValue.toString();
applyText(interfaceName);
}
}
});
}
private void applyText(String text) {
if (text == null || text.length() <= 0) {
return;
}
if (ifHasBeenWriten == 0) {
contentTextArea.setForeground(Color.black);
contentTextArea.setText(StringUtils.EMPTY);
ifHasBeenWriten = 1;
insertPosition = 0;
}
String textAll = contentTextArea.getText();
currentPosition = contentTextArea.getCaretPosition();
int insert = 0;
int current = 0;
if (insertPosition <= currentPosition) {
insert = insertPosition;
current = currentPosition;
} else {
insert = currentPosition;
current = insertPosition;
}
String beforeIndexOfInsertString = textAll.substring(0, insert);
String afterIndexofInsertString = textAll.substring(current);
contentTextArea.setText(beforeIndexOfInsertString + text + afterIndexofInsertString);
contentTextArea.getText();
contentTextArea.requestFocus();
insertPosition = contentTextArea.getCaretPosition();
}
private JPanel createNamePane(String name, JComponent comp) {
JPanel namePane = new JPanel(new BorderLayout(4, 4));
namePane.add(new UILabel(name), BorderLayout.NORTH);
namePane.add(comp, BorderLayout.CENTER);
return namePane;
}
private JPanel createTipsPane() {
JPanel tipsPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
tipsPane.setLayout(new BorderLayout(4, 4));
tipsPane.setBorder(BorderFactory.createEmptyBorder(30, 2, 0, 0));
JPanel searchPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
searchPane.setLayout(new BorderLayout(4, 4));
searchPane.add(keyWordTextField, BorderLayout.CENTER);
//搜索按钮
UIButton searchButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Search"));
searchButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String toFind = keyWordTextField.getText();
search(toFind);
popTips();
tipsList.requestFocusInWindow();
}
});
keyWordTextField.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_ENTER) {
e.consume();
String toFind = keyWordTextField.getText();
search(toFind);
popTips();
tipsList.requestFocusInWindow();
}
}
});
searchPane.add(searchButton, BorderLayout.EAST);
tipsPane.add(searchPane, BorderLayout.NORTH);
tipsList = new JList(tipsListModel);
tipsList.addMouseListener(tipsListMouseListener);
tipsList.addListSelectionListener(tipsListSelectionListener);
tipsList.addKeyListener(tipListKeyListener);
return tipsPane;
}
private void search(String key) {
tipsListModel.removeAllElements();
tipsListModel.clear();
key = key.replaceAll(StringUtils.BLANK, StringUtils.EMPTY);
ArrayList<String> list = new ArrayList<>();
if (!StringUtils.isEmpty(key)) {
List<String> allNames = JSAPITreeHelper.getAllNames();
for (String name : allNames) {
if (searchResult(key, name)) {
list.add(name);
}
}
String finalKey = key;
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int result;
boolean o1StartWidth = o1.toLowerCase().startsWith(finalKey.toLowerCase());
boolean o2StartWidth = o2.toLowerCase().startsWith(finalKey.toLowerCase());
if (o1StartWidth) {
result = o2StartWidth ? o1.compareTo(o2) : -1;
} else {
result = o2StartWidth ? 1 : o1.compareTo(o2);
}
return result;
}
});
for (String name : list) {
tipsListModel.addElement(name);
}
if (!tipsListModel.isEmpty()) {
tipsList.setSelectedIndex(0);
}
}
}
private boolean searchResult(String key, String interfaceName) {
if (StringUtils.isBlank(key) || StringUtils.isBlank(interfaceName)) {
return false;
}
int length = key.length();
String temp = interfaceName.toUpperCase();
for (int i = 0; i < length; i++) {
String check = key.substring(i, i + 1);
int index = temp.indexOf(check.toUpperCase());
if (index == -1) {
return false;
} else {
temp = temp.substring(index + 1);
}
}
return true;
}
private void initPopTips() {
popupMenu = new JPopupMenu();
JScrollPane tipsScrollPane = new JScrollPane(tipsList);
popupMenu.add(tipsScrollPane);
tipsScrollPane.setPreferredSize(new Dimension(220, 146));
tipsScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
}
private void popTips() {
popupMenu.show(keyWordTextField, 0, 23);
}
private ListSelectionListener tipsListSelectionListener = new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
Object selectValue = tipsList.getSelectedValue();
if (selectValue == null) {
return;
}
String interfaceName = selectValue.toString();
fixInterfaceNameList(interfaceName);
}
};
private KeyListener tipListKeyListener = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_ENTER) {
Object selectValue = tipsList.getSelectedValue();
if (selectValue == null) {
return;
}
tipListValueSelectAction(selectValue.toString());
if (popupMenu != null) {
popupMenu.setVisible(false);
}
contentTextArea.requestFocusInWindow();
}
}
};
private void tipListValueSelectAction(String value) {
if (ifHasBeenWriten == 0) {
contentTextArea.setForeground(Color.black);
contentTextArea.setText(StringUtils.EMPTY);
}
contentTextArea.setForeground(Color.black);
currentPosition = contentTextArea.getCaretPosition();
String output = value;
String textAll = contentTextArea.getText();
String textReplaced;
int position = 0;
if (insertPosition <= currentPosition) {
textReplaced = textAll.substring(0, insertPosition) + output + textAll.substring(currentPosition);
position = insertPosition + output.length();
} else {
textReplaced = textAll.substring(0, currentPosition) + output + textAll.substring(insertPosition);
position = currentPosition + output.length();
}
contentTextArea.setText(textReplaced);
contentTextArea.setCaretPosition(position);
insertPosition = position;
ifHasBeenWriten = 1;
tipsListModel.removeAllElements();
}
private MouseListener tipsListMouseListener = new MouseAdapter() {
String singlePressContent;
String doublePressContent;
@Override
public void mousePressed(MouseEvent e) {
int index = tipsList.getSelectedIndex();
if (index != -1) {
if (e.getClickCount() == 1) {
singlePressContent = (String) tipsListModel.getElementAt(index);
} else if (e.getClickCount() == 2) {
doublePressContent = (String) tipsListModel.getElementAt(index);
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
int index = tipsList.getSelectedIndex();
if (index != -1) {
if (e.getClickCount() == 1) {
if (ComparatorUtils.equals((String) tipsListModel.getElementAt(index), singlePressContent)) {
singleClickActuator(singlePressContent);
}
} else if (e.getClickCount() == 2) {
if (ComparatorUtils.equals((String) tipsListModel.getElementAt(index), doublePressContent)) {
doubleClickActuator(doublePressContent);
}
if (popupMenu != null) {
popupMenu.setVisible(false);
}
}
}
}
private void singleClickActuator(String currentLineContent) {
setDescription(currentLineContent);
fixInterfaceNameList(currentLineContent);
}
private void doubleClickActuator(String currentLineContent) {
tipListValueSelectAction(currentLineContent);
}
};
}

95
designer-base/src/main/java/com/fr/design/javascript/JavaScriptImplPane.java

@ -9,6 +9,8 @@ import com.fr.design.gui.itableeditorpane.UITableEditAction;
import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.hyperlink.AbstractHyperLinkPane;
import com.fr.design.javascript.jsapi.JSImplPopulateAction;
import com.fr.design.javascript.jsapi.JSImplUpdateAction;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.scrollruler.ModLineBorder;
import com.fr.design.utils.gui.GUICoreUtils;
@ -17,10 +19,16 @@ import com.fr.js.JavaScriptImpl;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import java.awt.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -28,11 +36,11 @@ import java.util.List;
public class JavaScriptImplPane extends AbstractHyperLinkPane<JavaScriptImpl> {
private static final int BOTTOM_BORDER = 12;
private UITextField itemNameTextField;
private JSContentPane jsPane;
protected JSContentPane jsPane;
private UITableEditorPane<String> importedJsPane;
private ReportletParameterViewPane parameterPane;
private String[] defaultArgs;
private boolean modal;
public JavaScriptImplPane() {
this(new String[0]);
@ -50,8 +58,57 @@ public class JavaScriptImplPane extends AbstractHyperLinkPane<JavaScriptImpl> {
initComponents();
}
public JavaScriptImplPane(String[] args, boolean modal) {
this.modal = modal;
this.defaultArgs = args;
initComponents();
}
protected void initComponents() {
parameterPane = new ReportletParameterViewPane(getChartParaType(), getValueEditorPane(), getValueEditorPane());
parameterPane = createParameterViewPane();
importedJsPane = createImportedJsPane();
importedJsPane.setPreferredSize(new Dimension(265, 150));
jsPane = createJSContentPane(defaultArgs);
jsPane.setBorder(BorderFactory.createTitledBorder(new ModLineBorder(ModLineBorder.TOP), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_JavaScript")));
parameterPane.setPreferredSize(new Dimension(265, 150));
JPanel topPane = new JPanel(new GridLayout(1,2));
topPane.add(importedJsPane);
topPane.add(parameterPane);
topPane.setBorder(BorderFactory.createEmptyBorder(0, 0, BOTTOM_BORDER, 0));
this.setLayout(new BorderLayout());
this.add(topPane, BorderLayout.NORTH);
this.add(jsPane, BorderLayout.CENTER);
this.reLayoutForChart();
}
protected JSContentPane createJSContentPane(String[] defaultArgs){
JSContentPane jsContentPane= new JSContentPane(defaultArgs,modal);
jsContentPane.setJsImplUpdateAction(new JSImplUpdateAction() {
@Override
public void update(JavaScriptImpl javaScript) {
if(javaScript != null){
updateBean(javaScript);
}
}
});
jsContentPane.setJsImplPopulateAction(new JSImplPopulateAction() {
@Override
public void populate(JavaScriptImpl javaScript) {
if(javaScript != null){
populateBean(javaScript);
}
}
});
return jsContentPane;
}
protected ReportletParameterViewPane createParameterViewPane(){
ReportletParameterViewPane parameterPane = new ReportletParameterViewPane(getChartParaType(), getValueEditorPane(), getValueEditorPane());
parameterPane.setBorder(BorderFactory.createTitledBorder(new ModLineBorder(ModLineBorder.TOP), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Parameter")));
parameterPane.addTableEditorListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
@ -72,7 +129,10 @@ public class JavaScriptImplPane extends AbstractHyperLinkPane<JavaScriptImpl> {
parameterChanger(list);
}
});
return parameterPane;
}
protected UITableEditorPane<String> createImportedJsPane(){
OneListTableModel<String> model = new OneListTableModel<String>(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_ReportServerP_Import_JavaScript"), this) {
public UITableEditAction[] createAction() {
@ -84,26 +144,12 @@ public class JavaScriptImplPane extends AbstractHyperLinkPane<JavaScriptImpl> {
return new AddJsAction();
}
};
importedJsPane = new UITableEditorPane<String>(model);
UITableEditorPane<String> importedJsPane = new UITableEditorPane<String>(model);
importedJsPane.setBorder(BorderFactory.createTitledBorder(new ModLineBorder(ModLineBorder.TOP), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_ReportServerP_Import_JavaScript")));
importedJsPane.setPreferredSize(new Dimension(265, 150));
jsPane = new JSContentPane(defaultArgs);
jsPane.setBorder(BorderFactory.createTitledBorder(new ModLineBorder(ModLineBorder.TOP), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_JavaScript")));
return importedJsPane;
}
parameterPane.setPreferredSize(new Dimension(265, 150));
JPanel topPane = GUICoreUtils.createBorderLayoutPane(
importedJsPane, BorderLayout.CENTER,
parameterPane, BorderLayout.EAST
);
topPane.setPreferredSize(new Dimension(300, 150));
topPane.setBorder(BorderFactory.createEmptyBorder(0, 0, BOTTOM_BORDER, 0));
this.setLayout(new BorderLayout());
this.add(topPane, BorderLayout.NORTH);
this.add(jsPane, BorderLayout.CENTER);
this.reLayoutForChart();
}
/**
* 参数改变
@ -140,10 +186,10 @@ public class JavaScriptImplPane extends AbstractHyperLinkPane<JavaScriptImpl> {
if (javaScriptImpl == null) {
javaScriptImpl = new JavaScriptImpl();
jsPane.reset();
}else{
} else {
jsPane.populate(javaScriptImpl.getContent());
}
jsPane.updateJSImpl(javaScriptImpl);
int rowCount = javaScriptImpl.getJSImportSize();
String[] value = new String[rowCount];
for (int i = 0; i < rowCount; i++) {
@ -160,6 +206,7 @@ public class JavaScriptImplPane extends AbstractHyperLinkPane<JavaScriptImpl> {
public JavaScriptImpl updateBean() {
JavaScriptImpl javaScript = new JavaScriptImpl();
updateBean(javaScript);
jsPane.updateJSImpl(javaScript);
return javaScript;
}

23
designer-base/src/main/java/com/fr/design/javascript/NewJavaScriptImplPane.java

@ -0,0 +1,23 @@
package com.fr.design.javascript;
import com.fr.js.JavaScriptImpl;
public class NewJavaScriptImplPane extends JavaScriptImplPane {
public NewJavaScriptImplPane(String[] args) {
super(args);
}
protected JSContentPane createJSContentPane(String[] defaultArgs){
return new JSContentWithDescriptionPane(defaultArgs);
}
public void populate(JavaScriptImpl javaScript) {
if (javaScript != null) {
populateBean(javaScript);
} else {
jsPane.reset();
}
}
}

21
designer-base/src/main/java/com/fr/design/javascript/jsapi/CategoryTreeNodesUserObject.java

@ -0,0 +1,21 @@
package com.fr.design.javascript.jsapi;
import com.fr.design.i18n.Toolkit;
public class CategoryTreeNodesUserObject implements JSAPIUserObject {
private String value;
public CategoryTreeNodesUserObject(String value) {
this.value = value;
}
@Override
public String getValue() {
return value;
}
@Override
public String getDisplayText() {
return Toolkit.i18nText(value);
}
}

155
designer-base/src/main/java/com/fr/design/javascript/jsapi/JSAPITreeHelper.java

@ -0,0 +1,155 @@
package com.fr.design.javascript.jsapi;
import com.fr.general.IOUtils;
import com.fr.json.JSONArray;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.tree.DefaultMutableTreeNode;
public class JSAPITreeHelper {
private static final String JSAPI_PATH = "com/fr/design/javascript/jsapi/jsapi.json";
private static final String CATEGORY_PATH = "com/fr/design/javascript/jsapi/category.json";
private static JSONObject categoryJSON ;
private static JSONObject jsapiJSON ;
static {
jsapiJSON = createJSON(JSAPI_PATH);
categoryJSON = createJSON(CATEGORY_PATH);
}
private static JSONObject createJSON(String path) {
StringBuilder jsonString = new StringBuilder(StringUtils.EMPTY);
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(IOUtils.readResource(path)))) {
String s;
while ((s = bufferedReader.readLine()) != null) {
jsonString.append(s);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return new JSONObject(jsonString.toString());
}
public static void createJSAPITree(DefaultMutableTreeNode rootNode) {
createJSAPITree(categoryJSON, rootNode);
}
public static String getDirectCategory(String name) {
if (jsapiJSON != null) {
Iterator<String> it = jsapiJSON.keys();
while (it.hasNext()) {
String key = it.next();
JSONArray nameArray = jsapiJSON.optJSONArray(key);
for (int i = 0; i < nameArray.length(); i++) {
if (StringUtils.equals(nameArray.getString(i), name)) {
return key;
}
}
}
}
return null;
}
private static void createJSAPITree(JSONObject jsonObject, DefaultMutableTreeNode rootNode) {
if (jsonObject != null && rootNode != null) {
Iterator<String> it = jsonObject.keys();
while (it.hasNext()) {
String key = it.next();
JSONObject subNode = jsonObject.optJSONObject(key);
if (subNode.size() == 0) {
rootNode.add(new DefaultMutableTreeNode(new CategoryTreeNodesUserObject(key)));
} else {
DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(new CategoryTreeNodesUserObject(key));
rootNode.add(treeNode);
createJSAPITree(subNode, treeNode);
}
}
}
}
private static List<String> getAllSubNodes(String name) {
return getAllSubNodes(name, categoryJSON);
}
public static List<String> getAllNames() {
ArrayList<String> result = new ArrayList<>();
if (jsapiJSON != null) {
Iterator<String> it = jsapiJSON.keys();
while (it.hasNext()) {
String key = it.next();
JSONArray nameArray = jsapiJSON.optJSONArray(key);
for (int i = 0; i < nameArray.length(); i++) {
result.add(nameArray.getString(i));
}
}
}
return result;
}
public static List<String> getNames(String category) {
ArrayList<String> result = new ArrayList<>();
List<String> subCategories = getAllSubNodes(category);
if (jsapiJSON != null) {
for (String subCategory : subCategories) {
if (jsapiJSON.containsKey(subCategory)) {
JSONArray nameArray = jsapiJSON.optJSONArray(subCategory);
for (int i = 0; i < nameArray.length(); i++) {
result.add(nameArray.getString(i));
}
}
}
}
return result;
}
private static List<String> getAllSubNodes(String name, JSONObject jsonObject) {
ArrayList<String> result = new ArrayList<>();
if (jsonObject != null) {
Iterator<String> it = jsonObject.keys();
while (it.hasNext()) {
String key = it.next();
JSONObject subNode = jsonObject.optJSONObject(key);
if (subNode.size() == 0) {
if (StringUtils.equals(key, name)) {
result.add(key);
return result;
}
} else {
if (StringUtils.equals(key, name)) {
result.add(key);
result.addAll(getAllSubNodes(subNode));
return result;
} else {
result.addAll(getAllSubNodes(name, subNode));
}
}
}
}
return result;
}
private static List<String> getAllSubNodes(JSONObject jsonObject) {
ArrayList<String> result = new ArrayList<>();
if (jsonObject != null) {
Iterator<String> it = jsonObject.keys();
while (it.hasNext()) {
String key = it.next();
JSONObject subNode = jsonObject.optJSONObject(key);
if (subNode.size() == 0) {
result.add(key);
} else {
result.add(key);
result.addAll(getAllSubNodes(subNode));
}
}
}
return result;
}
}

9
designer-base/src/main/java/com/fr/design/javascript/jsapi/JSAPIUserObject.java

@ -0,0 +1,9 @@
package com.fr.design.javascript.jsapi;
public interface JSAPIUserObject {
String getValue();
String getDisplayText();
}

7
designer-base/src/main/java/com/fr/design/javascript/jsapi/JSImplPopulateAction.java

@ -0,0 +1,7 @@
package com.fr.design.javascript.jsapi;
import com.fr.js.JavaScriptImpl;
public interface JSImplPopulateAction {
void populate(JavaScriptImpl javaScript);
}

7
designer-base/src/main/java/com/fr/design/javascript/jsapi/JSImplUpdateAction.java

@ -0,0 +1,7 @@
package com.fr.design.javascript.jsapi;
import com.fr.js.JavaScriptImpl;
public interface JSImplUpdateAction {
void update(JavaScriptImpl javaScript);
}

3
designer-base/src/main/java/com/fr/design/lock/LockInfoDialog.java

@ -3,6 +3,7 @@ package com.fr.design.lock;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
@ -44,7 +45,7 @@ public class LockInfoDialog extends JDialog {
panel.add(createControlPane(), BorderLayout.SOUTH);
this.getContentPane().add(panel);
this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Title_Hint"));
this.setSize(400, 160);
this.setSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.lock.LockInfoDialog"));
this.setResizable(false);
this.setModal(true);
GUICoreUtils.centerWindow(this);

3
designer-base/src/main/java/com/fr/design/mainframe/ForbiddenPane.java

@ -2,6 +2,7 @@ package com.fr.design.mainframe;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.guide.base.GuideView;
import com.fr.design.utils.gui.GUICoreUtils;
@ -105,7 +106,7 @@ public class ForbiddenPane extends JPanel {
super.paintComponent(g2d);
}
};
refreshButton.setPreferredSize(new Dimension(68, 24));
refreshButton.setPreferredSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.mainframe.ForbiddenPane.refreshButton"));
refreshButton.setForeground(Color.WHITE);
refreshButton.setBorderPainted(false);
refreshButton.setContentAreaFilled(false);

2
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java

@ -198,7 +198,7 @@ public class CellStyleEditPane extends MultiTabPane<ThemedCellStyle> {
@Override
protected void layoutContentPane() {
super.layoutContentPane();
leftcontentPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
leftcontentPane.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 5, original));
}
}
}

6
designer-base/src/main/java/com/fr/design/report/WatermarkSettingPane.java

@ -34,6 +34,7 @@ public class WatermarkSettingPane extends AbstractTemplateServerSettingPane {
@Override
protected void populateServerSettings() {
WatermarkAttr watermarkAttr = ReportUtils.getWatermarkAttrFromServerConfig();
watermarkAttr.setValid(true);
watermarkPane.populate(watermarkAttr);
}
@ -55,8 +56,9 @@ public class WatermarkSettingPane extends AbstractTemplateServerSettingPane {
public WatermarkAttr update() {
WatermarkAttr watermark = watermarkPane.update();
if (isUsingServerSettings()) {
watermark.setValid(false);
if (!isUsingServerSettings()) {
watermark.setValid(true);
watermark.setWaterMarkProvider(WaterMarkProvideConstant.TEMPLATE);
}
return watermark;
}

6
designer-base/src/main/java/com/fr/design/report/fit/AdaptiveFrmFitAttrModel.java

@ -13,11 +13,7 @@ import com.fr.report.fit.ReportFitAttr;
public class AdaptiveFrmFitAttrModel extends AbstractFitAttrModelProvider {
public FitType[] getFitTypes() {
return new FitType[]{
FitType.DOUBLE_FIT,
FitType.HORIZONTAL_FIT,
FitType.NOT_FIT
};
return new FitType[0];
}
public String getFitName() {

130
designer-base/src/main/java/com/fr/design/report/fit/BaseFitAttrPane.java

@ -2,27 +2,17 @@ package com.fr.design.report.fit;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.report.fit.menupane.FitPreviewPane;
import com.fr.design.report.fit.menupane.FitRadioGroup;
import com.fr.design.report.fit.menupane.FontRadioGroup;
import com.fr.design.report.fit.provider.FitAttrModelProvider;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils;
import com.fr.report.fit.ReportFitAttr;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Set;
import java.util.stream.Collectors;
@ -35,11 +25,8 @@ public abstract class BaseFitAttrPane extends BasicBeanPane<ReportFitAttr> {
protected UILabel belowSetLabel;
protected UIComboBox itemChoose;
protected java.util.List<FitAttrModel> fitAttrModelList = new ArrayList<>();
private ReportFitConfigPane fitConfigPane;
public FontRadioGroup fontRadioGroup;
public FitRadioGroup adaptRadioGroup;
public JPanel attrJPanel;
public FitPreviewPane previewJPanel;
public FitAttrModel fitAttrModel;
private static final int BELOW_SET_COMPONENT_HSPACE = 8;
@ -64,128 +51,27 @@ public abstract class BaseFitAttrPane extends BasicBeanPane<ReportFitAttr> {
protected void populateModel(FitAttrModel fitAttrModel) {
this.fitAttrModel = fitAttrModel;
if (attrJPanel != null) {
contentJPanel.remove(attrJPanel);
if (fitConfigPane != null) {
contentJPanel.remove(fitConfigPane);
}
if (previewJPanel != null) {
contentJPanel.remove(previewJPanel);
}
fontRadioGroup = new FontRadioGroup();
adaptRadioGroup = new FitRadioGroup();
initAttrJPanel();
initPreviewJPanel();
this.fitConfigPane = fitAttrModel instanceof CptFitAttrModel ? new ReportFitConfigPane(fitAttrModel, true) : new FormFitConfigPane(fitAttrModel, true);
contentJPanel.add(fitConfigPane);
}
protected void initAttrJPanel() {
int colCount = fitAttrModel.getFitTypes().length + 1;
Component[][] components = new Component[2][colCount];
initFitRadioGroup(fontRadioGroup, i18nText("Fine-Designer_Fit-Font"), new String[]{i18nText("Fine-Designer_Fit"), i18nText("Fine-Designer_Fit-No")}, components[0]);
initFitRadioGroup(adaptRadioGroup, fitAttrModel.getFitName(), Arrays.stream(fitAttrModel.getFitTypes()).map(FitType::description).toArray(String[]::new), components[1]);
double[] rowSize = new double[2];
double[] columnSize = new double[colCount];
for (int i = 0; i < rowSize.length; i++) {
rowSize[i] = 20;
}
for (int i = 0; i < columnSize.length; i++) {
if (i == 0) {
columnSize[i] = DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.report.fit.firstColumn").getWidth();
} else {
columnSize[i] = DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.report.fit.column").getWidth();
}
}
attrJPanel = TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize);
attrJPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0));
contentJPanel.add(attrJPanel);
}
private void initFitRadioGroup(FitRadioGroup fitRadioGroup, String name, String[] options, Component[] components) {
components[0] = new UILabel(name);
for (int i = 0; i < options.length; i++) {
if (options[i] != null) {
UIRadioButton fontFitRadio = new UIRadioButton(options[i]);
fitRadioGroup.add(fontFitRadio);
components[i + 1] = fontFitRadio;
} else {
components[i + 1] = null;
}
}
fitRadioGroup.addActionListener(getPreviewActionListener());
}
protected ActionListener getPreviewActionListener() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
refreshPreviewJPanel();
}
};
}
protected void refreshPreviewJPanel() {
String previewIndex = getPreviewIndex();
previewJPanel.refreshPreview(previewIndex, fontRadioGroup.isEnabled());
}
protected String getPreviewIndex() {
return getStateInPC(adaptRadioGroup.getSelectRadioIndex()) + "" + fontRadioGroup.getSelectRadioIndex();
}
protected void initPreviewJPanel() {
previewJPanel = new FitPreviewPane();
previewJPanel.setBorder(BorderFactory.createEmptyBorder(0, getPreviewJPanelLeft(), 0, 0));
contentJPanel.add(previewJPanel);
}
private int getPreviewJPanelLeft() {
int left = 0;
if (belowSetLabel.getPreferredSize() != null) {
left = belowSetLabel.getPreferredSize().width + BELOW_SET_COMPONENT_HSPACE;
}
return left;
}
protected int getStateInPC(int index) {
FitType[] fitTypes = fitAttrModel.getFitTypes();
return fitTypes[index].getState();
}
protected int getOptionIndex(int state) {
FitType[] fitTypes = fitAttrModel.getFitTypes();
for (int i = 0; i < fitTypes.length; i++) {
if (ComparatorUtils.equals(state, fitTypes[i].getState())) {
return i;
}
}
return 0;
}
@Override
public void populateBean(ReportFitAttr ob) {
fontRadioGroup.selectIndexButton(ob.isFitFont() ? 0 : 1);
adaptRadioGroup.selectIndexButton(getOptionIndex(ob.fitStateInPC()));
refreshPreviewJPanel();
this.fitConfigPane.populateBean(ob);
}
@Override
public ReportFitAttr updateBean() {
ReportFitAttr reportFitAttr = new ReportFitAttr();
reportFitAttr.setFitFont(fontRadioGroup.isFontFit());
reportFitAttr.setFitStateInPC(getStateInPC(adaptRadioGroup.getSelectRadioIndex()));
return reportFitAttr;
return this.fitConfigPane.updateBean();
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
fontRadioGroup.setEnabled(enabled);
adaptRadioGroup.setEnabled(enabled);
refreshPreviewJPanel();
this.fitConfigPane.setEnabled(enabled);
}
@Override

9
designer-base/src/main/java/com/fr/design/report/fit/FitAttrModel.java

@ -3,6 +3,8 @@ package com.fr.design.report.fit;
import com.fr.design.mainframe.JTemplate;
import com.fr.report.fit.ReportFitAttr;
import java.util.Arrays;
public interface FitAttrModel {
/**
* @Description 名称比如普通报表决策报表等
@ -19,6 +21,12 @@ public interface FitAttrModel {
**/
FitType[] getFitTypes();
/**
* @Description 表格自适应选项名称集合
**/
default String[] getFitTypeNames(){
return Arrays.stream(getFitTypes()).map(FitType::description).toArray(String[]::new);
}
/**
* @Description 获取全局的自适应属性
@ -41,4 +49,5 @@ public interface FitAttrModel {
* @param: jTemplate
**/
boolean isAvailable(JTemplate jTemplate);
}

11
designer-base/src/main/java/com/fr/design/report/fit/FitType.java

@ -60,6 +60,17 @@ public enum FitType {
return DEFAULT;
}
public static FitType parseByFitState(int state) {
for (FitType attrState : values()) {
if (attrState.state == state) {
return attrState;
}
}
return DEFAULT;
}
public int getState() {
return this.state;
}

128
designer-base/src/main/java/com/fr/design/report/fit/FormFitAttrModelType.java

@ -0,0 +1,128 @@
package com.fr.design.report.fit;
import com.fr.design.designer.properties.items.Item;
import com.fr.form.fit.common.LightTool;
import com.fr.form.main.BodyScaleAttrTransformer;
import com.fr.form.main.Form;
import com.fr.form.ui.container.WAbsoluteLayout;
import com.fr.form.ui.container.WBodyLayoutType;
import com.fr.form.ui.container.WFitLayout;
public enum FormFitAttrModelType {
PLAIN_FORM_FIT_ATTR_MODEL {
@Override
public FitAttrModel getFitAttrModel() {
return new FrmFitAttrModel();
}
@Override
public Item[] getFitLayoutScaleAttr() {
return new Item[]{
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Bidirectional_Adaptive"), WFitLayout.STATE_FULL),
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Horizontal_Adaptive"), WFitLayout.STATE_ORIGIN)};
}
@Override
public Item[] getAbsoluteLayoutSaleAttr() {
return new Item[]{
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode_Fit"), WAbsoluteLayout.STATE_FIT),
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode_Fixed"), WAbsoluteLayout.STATE_FIXED)
};
}
@Override
public int getScaleAttrShowIndex(WFitLayout wFitLayout) {
int scale = wFitLayout.getScaleAttr();
if (wFitLayout.getBodyLayoutType() == WBodyLayoutType.FIT) {
return BodyScaleAttrTransformer.getFitBodyCompStateFromScaleAttr(scale);
} else {
return BodyScaleAttrTransformer.getAbsoluteBodyCompStateFromScaleAttr(scale);
}
}
@Override
public int parseScaleAttrFromShowIndex(int showIndex, WBodyLayoutType wBodyLayoutType) {
if (wBodyLayoutType == WBodyLayoutType.FIT) {
if (showIndex == 0) {
return WFitLayout.SCALE_FULL;
} else {
return WFitLayout.SCALE_HOR;
}
} else {
if (showIndex == 0) {
return WFitLayout.SCALE_FULL;
} else {
return WFitLayout.SCALE_NO;
}
}
}
},
NEW_FORM_FIT_ATTR_MODEL {
@Override
public FitAttrModel getFitAttrModel() {
return new AdaptiveFrmFitAttrModel();
}
@Override
public Item[] getFitLayoutScaleAttr() {
return new Item[]{
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Bidirectional_Adaptive"), WFitLayout.STATE_FULL),
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Horizontal_Adaptive"), WFitLayout.STATE_ORIGIN),
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode_Fixed"), 2)};
}
@Override
public Item[] getAbsoluteLayoutSaleAttr() {
return new Item[]{
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Bidirectional_Adaptive"), WFitLayout.STATE_FULL),
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Horizontal_Adaptive"), WFitLayout.STATE_ORIGIN),
new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode_Fixed"), 2)};
}
@Override
public int getScaleAttrShowIndex(WFitLayout wFitLayout) {
int scale = wFitLayout.getScaleAttr();
if (scale == WFitLayout.SCALE_NO) {
return 2;
} else if (scale == WFitLayout.SCALE_HOR) {
return 1;
} else {
return 0;
}
}
@Override
public int parseScaleAttrFromShowIndex(int showIndex, WBodyLayoutType wBodyLayoutType) {
if (showIndex == 0) {
return WFitLayout.SCALE_FULL;
} else if (showIndex == 1) {
return WFitLayout.SCALE_HOR;
} else {
return WFitLayout.SCALE_NO;
}
}
};
public abstract FitAttrModel getFitAttrModel();
public abstract Item[] getFitLayoutScaleAttr();
public abstract Item[] getAbsoluteLayoutSaleAttr();
public abstract int getScaleAttrShowIndex(WFitLayout wFitLayout);
public abstract int parseScaleAttrFromShowIndex(int showIndex, WBodyLayoutType wBodyLayoutType);
public static FormFitAttrModelType parse(Form form) {
return LightTool.containNewFormFlag(form) ? NEW_FORM_FIT_ATTR_MODEL : PLAIN_FORM_FIT_ATTR_MODEL;
}
}

59
designer-base/src/main/java/com/fr/design/report/fit/FormFitConfigPane.java

@ -0,0 +1,59 @@
package com.fr.design.report.fit;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.report.fit.ReportFitAttr;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
public class FormFitConfigPane extends ReportFitConfigPane {
private static final int DEFAULT_ITEM = 0;
private static final int CUSTOM_ITEM = 1;
public FormFitConfigPane(FitAttrModel fitAttrModel) {
this(fitAttrModel, false);
}
public FormFitConfigPane(FitAttrModel fitAttrModel, boolean globalConfig) {
super(fitAttrModel, globalConfig);
}
protected JPanel initECConfigPane() {
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
if (fitAttrModel.getFitTypeNames().length != 0) {
Component[] ecComponents = new Component[fitAttrModel.getFitTypeNames().length + 1];
initRadioGroup(ecConfigRadioGroup, fitAttrModel.getFitName(), fitAttrModel.getFitTypeNames(), ecComponents);
jPanel.add(createSubAttrPane(ecComponents), BorderLayout.CENTER);
jPanel.add(createTipPane(), BorderLayout.SOUTH);
}
return jPanel;
}
private JPanel createTipPane() {
JPanel jPanel = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true);
UILabel label1 = new UILabel(Toolkit.i18nText("Fine-Design_Form_PC_FIT_Config_Tip1"));
jPanel.add(label1);
label1.setForeground(Color.lightGray);
UILabel label2 = new UILabel(Toolkit.i18nText("Fine-Design_Form_PC_FIT_Config_Tip2"));
jPanel.add(label2);
label2.setForeground(Color.lightGray);
return jPanel;
}
protected void refreshPreviewJPanel() {
previewJPanel.refreshPreview(fontRadioGroup.isFontFit());
}
protected void populateECConfigRadioGroup(int fitStateInPC) {
ecConfigRadioGroup.selectIndexButton(fitStateInPC == 0 ? DEFAULT_ITEM : CUSTOM_ITEM);
}
protected void updateECConfigRadioGroup(ReportFitAttr reportFitAttr) {
reportFitAttr.setFitStateInPC(ecConfigRadioGroup.getSelectRadioIndex());
}
}

9
designer-base/src/main/java/com/fr/design/report/fit/FrmFitAttrModel.java

@ -17,7 +17,7 @@ public class FrmFitAttrModel implements FitAttrModel {
@Override
public String getFitName() {
return Toolkit.i18nText("Fine-Designer_Fit-Element");
return Toolkit.i18nText("Fine-Design_Form_PC_FIT_Config_EC_Label");
}
public FitType[] getFitTypes() {
@ -29,6 +29,13 @@ public class FrmFitAttrModel implements FitAttrModel {
};
}
@Override
public String[] getFitTypeNames() {
return new String[]{
Toolkit.i18nText("Fine-Designer_Fit-Default"), Toolkit.i18nText("Fine-Design_Basic_Custom")
};
}
@Override
public ReportFitAttr getGlobalReportFitAttr() {
return ReportFitConfig.getInstance().getFrmFitAttr();

71
designer-base/src/main/java/com/fr/design/report/fit/NewFitPreviewPane.java

@ -0,0 +1,71 @@
package com.fr.design.report.fit;
import com.fr.base.GraphHelper;
import com.fr.general.FRFont;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
public class NewFitPreviewPane extends JPanel {
private boolean fitFont = false;
private FitType fitType = FitType.DOUBLE_FIT;
private static final Color DEFAULT_PAINT_COLOR = Color.decode("#419BF9");
private static final int FIT_FONT_SIZE = 15;
private static final int NO_FIT_FONT_SIZE = 9;
private static final Dimension NO_FIT_CONTAINER_DIMENSION = new Dimension(200, 136);
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.GRAY);
GraphHelper.drawRect(g, 1, 1, this.getWidth() - 2, this.getHeight() - 2);
g.setColor(DEFAULT_PAINT_COLOR);
FRFont textFont = FRFont.getInstance(FRFont.DEFAULT_FONTNAME, Font.PLAIN, fitFont ? FIT_FONT_SIZE : NO_FIT_FONT_SIZE);
g.setFont(textFont);
Dimension dimension = calculateCellDimension();
GraphHelper.drawLine(g, 1, dimension.height, dimension.width * 2 - 1, dimension.height);
GraphHelper.drawLine(g, dimension.width, 1, dimension.width, dimension.height * 2 - 1);
GraphHelper.drawRect(g, 1, 1, dimension.width * 2 - 2, dimension.height * 2 - 2);
double startX = calculateTextDrawStartX(dimension.width, this.getFontMetrics(textFont), "text1");
double startY = calculateTextDrawStartY(dimension.height);
GraphHelper.drawString(g, "text1", startX, startY);
GraphHelper.drawString(g, "text2", dimension.width + startX, startY);
GraphHelper.drawString(g, "text3", startX, dimension.height + startY);
GraphHelper.drawString(g, "text4", dimension.width + startX, dimension.height + startY);
}
private Dimension calculateCellDimension() {
if (fitType == FitType.DOUBLE_FIT) {
return new Dimension(this.getWidth() / 2, this.getHeight() / 2);
} else if (fitType == FitType.NOT_FIT) {
return new Dimension(NO_FIT_CONTAINER_DIMENSION.width / 2, NO_FIT_CONTAINER_DIMENSION.height / 2);
} else {
return new Dimension(this.getWidth() / 2, NO_FIT_CONTAINER_DIMENSION.height / 2);
}
}
private double calculateTextDrawStartX(int containerWidth, FontMetrics fontMetrics, String text) {
return (containerWidth - fontMetrics.stringWidth(text)) / 2.0D;
}
private double calculateTextDrawStartY(int containerHeight) {
return containerHeight / 2.0D;
}
public void refreshPreview(boolean fitFont, FitType fitType) {
this.fitFont = fitFont;
this.fitType = fitType;
repaint();
}
public void refreshPreview(boolean fitFont) {
this.fitFont = fitFont;
repaint();
}
}

172
designer-base/src/main/java/com/fr/design/report/fit/ReportFitConfigPane.java

@ -0,0 +1,172 @@
package com.fr.design.report.fit;
import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.report.fit.menupane.FitRadioGroup;
import com.fr.design.report.fit.menupane.FontRadioGroup;
import com.fr.general.ComparatorUtils;
import com.fr.report.fit.ReportFitAttr;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static com.fr.design.i18n.Toolkit.i18nText;
public class ReportFitConfigPane extends JPanel {
public FontRadioGroup fontRadioGroup;
public FitRadioGroup ecConfigRadioGroup;
protected NewFitPreviewPane previewJPanel;
protected FitAttrModel fitAttrModel;
protected boolean globalConfig;
public ReportFitConfigPane(FitAttrModel fitAttrModel, boolean globalConfig) {
this.fitAttrModel = fitAttrModel;
this.globalConfig = globalConfig;
initComponent();
}
private void initComponent() {
JPanel contentJPanel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(false, FlowLayout.LEFT, 0, 0);
this.add(contentJPanel);
fontRadioGroup = new FontRadioGroup();
ecConfigRadioGroup = new FitRadioGroup();
contentJPanel.add(initAttrJPanel());
contentJPanel.add(initPreviewJPanel());
}
private JPanel initAttrJPanel() {
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
Component[] fontComponents = new Component[3];
initRadioGroup(fontRadioGroup, i18nText("Fine-Designer_Fit-Font"), new String[]{i18nText("Fine-Designer_Fit"), i18nText("Fine-Designer_Fit-No")}, fontComponents);
jPanel.add(createSubAttrPane(fontComponents), BorderLayout.NORTH);
jPanel.add(initECConfigPane(), BorderLayout.CENTER);
return jPanel;
}
protected JPanel initECConfigPane() {
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
Component[] ecComponents = new Component[fitAttrModel.getFitTypeNames().length + 1];
initRadioGroup(ecConfigRadioGroup, fitAttrModel.getFitName(), fitAttrModel.getFitTypeNames(), ecComponents);
jPanel.add(createSubAttrPane(ecComponents), BorderLayout.CENTER);
return jPanel;
}
protected JPanel createSubAttrPane(Component[] components) {
double[] rowSize = new double[]{20};
double[] columnSize = new double[components.length];
for (int i = 0; i < columnSize.length; i++) {
if (i == 0) {
columnSize[i] = DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.report.fit.firstColumn").getWidth();
} else {
columnSize[i] = DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.report.fit.column").getWidth();
}
}
JPanel attrJPanel = TableLayoutHelper.createTableLayoutPane(new Component[][]{components}, rowSize, columnSize);
attrJPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0));
return attrJPanel;
}
protected void initRadioGroup(FitRadioGroup fitRadioGroup, String name, String[] options, Component[] components) {
components[0] = new UILabel(name);
for (int i = 0; i < options.length; i++) {
if (options[i] != null) {
UIRadioButton fontFitRadio = new UIRadioButton(options[i]);
fitRadioGroup.add(fontFitRadio);
components[i + 1] = fontFitRadio;
} else {
components[i + 1] = null;
}
}
fitRadioGroup.addActionListener(getPreviewActionListener());
}
private ActionListener getPreviewActionListener() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
refreshPreviewJPanel();
}
};
}
public void refreshPreviewJPanel(FitType fitType) {
previewJPanel.refreshPreview(fontRadioGroup.isFontFit(), fitType);
}
protected void refreshPreviewJPanel() {
previewJPanel.refreshPreview(fontRadioGroup.isFontFit(), FitType.parse(updateBean()));
}
private JPanel initPreviewJPanel() {
JPanel wrapperPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
previewJPanel = new NewFitPreviewPane();
wrapperPane.add(previewJPanel, BorderLayout.CENTER);
int leftIndent = globalConfig ? (int) DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.report.fit.firstColumn").getWidth() : 0;
wrapperPane.setBorder(BorderFactory.createEmptyBorder(0, leftIndent, 0, 0));
wrapperPane.setPreferredSize(new Dimension(300 + leftIndent, 204));
return wrapperPane;
}
public void populateBean(ReportFitAttr ob) {
fontRadioGroup.selectIndexButton(ob.isFitFont() ? 0 : 1);
populateECConfigRadioGroup(ob.fitStateInPC());
refreshPreviewJPanel();
}
protected void populateECConfigRadioGroup(int fitStateInPC){
ecConfigRadioGroup.selectIndexButton(getOptionIndex(fitStateInPC));
}
protected void updateECConfigRadioGroup(ReportFitAttr reportFitAttr){
reportFitAttr.setFitStateInPC(getStateInPC(ecConfigRadioGroup.getSelectRadioIndex()));
}
public ReportFitAttr updateBean() {
ReportFitAttr reportFitAttr = new ReportFitAttr();
reportFitAttr.setFitFont(fontRadioGroup.isFontFit());
updateECConfigRadioGroup(reportFitAttr);
return reportFitAttr;
}
protected int getStateInPC(int index) {
FitType[] fitTypes = fitAttrModel.getFitTypes();
if (index > fitTypes.length - 1) {
return index;
}
return fitTypes[index].getState();
}
protected int getOptionIndex(int state) {
FitType[] fitTypes = fitAttrModel.getFitTypes();
for (int i = 0; i < fitTypes.length; i++) {
if (ComparatorUtils.equals(state, fitTypes[i].getState())) {
return i;
}
}
return 0;
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
fontRadioGroup.setEnabled(enabled);
ecConfigRadioGroup.setEnabled(enabled);
}
}

41
designer-base/src/main/java/com/fr/design/web/CustomIconPane.java

@ -4,14 +4,14 @@ import com.fr.base.BaseUtils;
import com.fr.base.GraphHelper;
import com.fr.base.Icon;
import com.fr.base.IconManager;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ifilechooser.FileChooserArgs;
import com.fr.design.gui.ifilechooser.FileChooserFactory;
import com.fr.design.gui.ifilechooser.FileChooserProvider;
import com.fr.design.gui.ifilechooser.JavaFxNativeFileChooser;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.iscrollbar.UIScrollBar;
import com.fr.design.gui.itextarea.DescriptionTextArea;
@ -30,23 +30,35 @@ import com.fr.stable.ListMap;
import com.fr.stable.StringUtils;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerFacade;
import javafx.stage.FileChooser;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Window;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* carl自定义Icon编辑
@ -414,7 +426,7 @@ public class CustomIconPane extends BasicPane {
browseButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onBrowseButtonClicked();
onBrowseButtonClicked(SwingUtilities.getWindowAncestor(EditIconDialog.this));
}
});
@ -449,12 +461,11 @@ public class CustomIconPane extends BasicPane {
this.add(centerPane, BorderLayout.CENTER);
}
private void onBrowseButtonClicked() {
private void onBrowseButtonClicked(Window parent) {
// carl:不知道是否只要png格式,反正导出时全部都转成png了
FileChooserProvider fileChooserProvider = new JavaFxNativeFileChooser.Builder().
filter("Icon Image File", "*.jpg", "*.jpeg", "*.png", "*.gif").
build();
if (JFileChooser.APPROVE_OPTION == fileChooserProvider.showDialog(DesignerContext.getDesignerFrame())) {
FileChooserProvider fileChooserProvider = FileChooserFactory.createFileChooser(FileChooserArgs.newBuilder().
setFilter("Icon Image File", "*.jpg", "*.jpeg", "*.png", "*.gif").build());
if (JFileChooser.APPROVE_OPTION == fileChooserProvider.showDialog(parent)) {
String path = fileChooserProvider.getSelectedFile().getAbsolutePath();
// 图片存储有最大值48*48限制,没有超过最大值时,按原图大小存储,超过最大值后,压缩至最大值存储
Image image = BaseUtils.readImage(path);

9
designer-base/src/main/java/com/fr/design/worker/save/CallbackSaveWorker.java

@ -63,6 +63,15 @@ public class CallbackSaveWorker extends SaveWorker {
}
}
public void addSuccessCallbackBeforeLast(Runnable successRunnable) {
if (successRunnableList == null) {
successRunnableList = new LinkedList<>();
}
if (successRunnable != null) {
successRunnableList.add(successRunnableList.size() - 1, successRunnable);
}
}
public void addFailCallback(Runnable failRunnable) {
if (failRunnableList == null) {
failRunnableList = new LinkedList<>();

4
designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties

@ -12,4 +12,6 @@ com.fr.design.web.pane.text.field=450*20
com.fr.design.actions.server.dialog=800*630
com.fr.design.report.fit.templatePane.dialog=800*400
com.fr.design.report.fit.firstColumn=120*20
com.fr.design.report.fit.column=160*20
com.fr.design.report.fit.column=160*20
com.fr.design.lock.LockInfoDialog=500*180
com.fr.design.mainframe.ForbiddenPane.refreshButton=75*24

4
designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties

@ -11,4 +11,6 @@ com.fr.design.web.pane.text.field=400*20
com.fr.design.actions.server.dialog=700*630
com.fr.design.report.fit.templatePane.dialog=600*400
com.fr.design.report.fit.firstColumn=170*20
com.fr.design.report.fit.column=100*20
com.fr.design.report.fit.column=100*20
com.fr.design.lock.LockInfoDialog=500*180
com.fr.design.mainframe.ForbiddenPane.refreshButton=68*24

4
designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties

@ -11,4 +11,6 @@ com.fr.design.web.pane.text.field=450*20
com.fr.design.actions.server.dialog=700*630
com.fr.design.report.fit.templatePane.dialog=600*400
com.fr.design.report.fit.firstColumn=130*20
com.fr.design.report.fit.column=100*20
com.fr.design.report.fit.column=100*20
com.fr.design.lock.LockInfoDialog=500*180
com.fr.design.mainframe.ForbiddenPane.refreshButton=80*24

4
designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties

@ -12,4 +12,6 @@ com.fr.design.web.pane.text.field=450*20
com.fr.design.actions.server.dialog=700*630
com.fr.design.report.fit.templatePane.dialog=600*400
com.fr.design.report.fit.firstColumn=80*20
com.fr.design.report.fit.column=100*20
com.fr.design.report.fit.column=100*20
com.fr.design.lock.LockInfoDialog=400*160
com.fr.design.mainframe.ForbiddenPane.refreshButton=68*24

4
designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties

@ -11,4 +11,6 @@ com.fr.design.web.pane.text.field=450*20
com.fr.design.actions.server.dialog=700*630
com.fr.design.report.fit.templatePane.dialog=600*400
com.fr.design.report.fit.firstColumn=80*20
com.fr.design.report.fit.column=100*20
com.fr.design.report.fit.column=100*20
com.fr.design.lock.LockInfoDialog=400*160
com.fr.design.mainframe.ForbiddenPane.refreshButton=68*24

47
designer-base/src/main/resources/com/fr/design/javascript/jsapi/category.json

@ -0,0 +1,47 @@
{
"Fine-Design_JSAPI_Public_Module": {
"Fine-Design_JSAPI_Public_Module_Global": {
"Fine-Design_JSAPI_Public_Module_Global_Universal": {},
"Fine-Design_JSAPI_Public_Module_Global_FR": {},
"Fine-Design_JSAPI_Public_Module_Global_FS": {},
"Fine-Design_JSAPI_Public_Module_Global_Mobile": {}
},
"Fine-Design_JSAPI_Public_Module_Widget": {
"Fine-Design_JSAPI_Public_Module_Widget_Get": {},
"Fine-Design_JSAPI_Public_Module_Widget_Universal": {},
"Fine-Design_JSAPI_Public_Module_Date_Widget_Peculiar": {},
"Fine-Design_JSAPI_Public_Module_Button_Widget_Peculiar": {},
"Fine-Design_JSAPI_Public_Module_Combobox_Widget_Peculiar": {}
},
"Fine-Design_JSAPI_Public_Module_Table": {
"Fine-Design_JSAPI_Public_Module_Table_Marquee": {},
"Fine-Design_JSAPI_Public_Module_Table_Scrollbar": {},
"Fine-Design_JSAPI_Public_Module_Table_Cell_Style": {},
"Fine-Design_JSAPI_Public_Module_Table_Row_Height_Col_Width": {},
"Fine-Design_JSAPI_Public_Module_Table_Cell_Value": {},
"Fine-Design_JSAPI_Public_Module_Table_Cell_Radius": {}
},
"Fine-Design_JSAPI_Public_Module_Toolbar": {
"Fine-Design_JSAPI_Public_Module_Toolbar_Email_Button": {}
},
"Fine-Design_JSAPI_Public_Module_Report_Page": {
"Fine-Design_JSAPI_Public_Module_Report_Page_Jump": {},
"Fine-Design_JSAPI_Public_Module_Report_Page_Number_Get": {}
},
"Fine-Design_JSAPI_Public_Module_Report_Export": {}
},
"Fine-Design_JSAPI_Cpt": {
"Fine-Design_JSAPI_Cpt_Page_Preview": {
"Fine-Design_JSAPI_Cpt_Page_Preview_Folding_Tree": {}
},
"Fine-Design_JSAPI_Cpt_Write_Preview": {},
"Fine-Design_JSAPI_Cpt_View_Preview": {
"Fine-Design_JSAPI_Cpt_View_Preview_Report_Location": {}
}
},
"Fine-Design_JSAPI_Form": {
"Fine-Design_JSAPI_Form_Component_Get": {},
"Fine-Design_JSAPI_Form_Component_Universal": {},
"Fine-Design_JSAPI_Form_Component_Tab": {}
}
}

33
designer-base/src/main/resources/com/fr/design/javascript/jsapi/jsapi.json

@ -0,0 +1,33 @@
{
"Fine-Design_JSAPI_Public_Module_Global_Universal": ["_g()", "getParameterContainer", "parameterCommit", "loadContentPane", "getPreviewType"],
"Fine-Design_JSAPI_Public_Module_Global_FR": [ "servletURL", "serverURL", "server", "fineServletURL", "SessionMgr.getSessionID", "showDialog", "closeDialog",
"doHyperlinkByGet", "doHyperlinkByPost", "doURLPrint", "Msg", "remoteEvaluate", "jsonEncode", "jsonDecode",
"ajax", "isEmpty", "isArray", "cellStr2ColumnRow", "columnRow2CellStr"],
"Fine-Design_JSAPI_Public_Module_Global_FS": ["signOut", "tabPane.closeActiveTab", "tabPane.addItem"],
"Fine-Design_JSAPI_Public_Module_Global_Mobile": ["location", "Mobile.getDeviceInfo"],
"Fine-Design_JSAPI_Public_Module_Widget_Get": ["this", "this.options.form", "getWidgetByName"],
"Fine-Design_JSAPI_Public_Module_Widget_Universal": ["getValue", "getText", "setValue", "visible", "invisible", "setVisible", "isVisible", "setEnable", "isEnabled",
"reset", "getType", "setWaterMark", "fireEvent", "setPopupStyle"],
"Fine-Design_JSAPI_Public_Module_Date_Widget_Peculiar":["setMaxAndMinDate"],
"Fine-Design_JSAPI_Public_Module_Button_Widget_Peculiar":["doClick"],
"Fine-Design_JSAPI_Public_Module_Combobox_Widget_Peculiar":["setName4Empty"],
"Fine-Design_JSAPI_Public_Module_Table_Marquee":["startMarquee", "stopMarquee"],
"Fine-Design_JSAPI_Public_Module_Table_Scrollbar":["setHScrollBarVisible", "setVScrollBarVisible"],
"Fine-Design_JSAPI_Public_Module_Table_Cell_Style":["addEffect"],
"Fine-Design_JSAPI_Public_Module_Table_Row_Height_Col_Width":["setRowHeight", "setColWidth"],
"Fine-Design_JSAPI_Public_Module_Table_Cell_Value":["getCellValue", "setCellValue"],
"Fine-Design_JSAPI_Public_Module_Table_Cell_Radius":["setCellRadius"],
"Fine-Design_JSAPI_Public_Module_Toolbar":["toolBarFloat", "setStyle","getToolbar"],
"Fine-Design_JSAPI_Public_Module_Toolbar_Email_Button":["changeFormat"],
"Fine-Design_JSAPI_Public_Module_Report_Page_Jump":["gotoPreviousPage", "gotoNextPage", "gotoLastPage", "gotoFirstPage", "gotoPage"],
"Fine-Design_JSAPI_Public_Module_Report_Page_Number_Get":["getCurrentPageIndex", "getReportTotalPage", "currentPageIndex", "reportTotalPage"],
"Fine-Design_JSAPI_Public_Module_Report_Export":["exportReportToExcel", "exportReportToImage", "exportReportToPDF", "exportReportToWord"],
"Fine-Design_JSAPI_Cpt_Page_Preview_Folding_Tree":["expandNodeLayer", "collapseNodeLayer", "expandAllNodeLayer", "collapseAllNodeLayer"],
"Fine-Design_JSAPI_Cpt_Write_Preview":["getWidgetByCell", "appendReportRC", "appendReportRow",
"deleteReportRC", "deleteRows", "refreshAllSheets", "loadSheetByIndex", "loadSheetByName", "isDirtyPage",
"isAutoStash", "writeReport", "verifyAndWriteReport", "verifyReport", "importExcel", "importExcel_Clean",
"importExcel_Append", "importExcel_Cover", "stash", "clear"],
"Fine-Design_JSAPI_Cpt_View_Preview_Report_Location":["centerReport"],
"Fine-Design_JSAPI_Form_Component_Get":["getAllWidgets"],
"Fine-Design_JSAPI_Form_Component_Tab":["showCardByIndex", "showCardByIndex", "getShowIndex", "setTitleVisible"]
}

31
designer-base/src/test/java/com/fr/design/javascript/jsapi/JSAPITreeHelperTest.java

@ -0,0 +1,31 @@
package com.fr.design.javascript.jsapi;
import java.util.List;
import javax.swing.tree.DefaultMutableTreeNode;
import junit.framework.TestCase;
public class JSAPITreeHelperTest extends TestCase {
public void testGetName(){
List<String> names = JSAPITreeHelper.getNames("Fine-Design_JSAPI_Public_Module_Toolbar");
assertEquals(names.size(),4);
assertTrue(names.contains( "toolBarFloat"));
assertTrue(names.contains( "setStyle"));
assertTrue(names.contains( "getToolbar"));
assertTrue(names.contains( "changeFormat"));
List<String> allNames = JSAPITreeHelper.getAllNames();
assertEquals(allNames.size(),16);
}
public void testGetDirectCategory(){
String directCategory = JSAPITreeHelper.getDirectCategory("_g()");
assertEquals(directCategory,"Fine-Design_JSAPI_Public_Module_Global_Universal");
directCategory = JSAPITreeHelper.getDirectCategory("showCardByIndex");
assertEquals(directCategory,"Fine-Design_JSAPI_Form_Component_Tab");
}
public void testCreateJSAPITree(){
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
JSAPITreeHelper.createJSAPITree(rootNode);
assertEquals(2,rootNode.getChildCount());
}
}

17
designer-base/src/test/resources/com/fr/design/javascript/jsapi/category.json

@ -0,0 +1,17 @@
{
"Fine-Design_JSAPI_Public_Module": {
"Fine-Design_JSAPI_Public_Module_Global": {
"Fine-Design_JSAPI_Public_Module_Global_Universal": {},
"Fine-Design_JSAPI_Public_Module_Global_Mobile": {}
},
"Fine-Design_JSAPI_Public_Module_Widget": {
"Fine-Design_JSAPI_Public_Module_Date_Widget_Peculiar": {}
},
"Fine-Design_JSAPI_Public_Module_Toolbar": {
"Fine-Design_JSAPI_Public_Module_Toolbar_Email_Button": {}
}
},
"Fine-Design_JSAPI_Form": {
"Fine-Design_JSAPI_Form_Component_Tab": {}
}
}

8
designer-base/src/test/resources/com/fr/design/javascript/jsapi/jsapi.json

@ -0,0 +1,8 @@
{
"Fine-Design_JSAPI_Public_Module_Global_Universal": ["_g()", "getParameterContainer", "parameterCommit", "loadContentPane", "getPreviewType"],
"Fine-Design_JSAPI_Public_Module_Global_Mobile": ["location", "Mobile.getDeviceInfo"],
"Fine-Design_JSAPI_Public_Module_Date_Widget_Peculiar":["setMaxAndMinDate"],
"Fine-Design_JSAPI_Public_Module_Toolbar":["toolBarFloat", "setStyle","getToolbar"],
"Fine-Design_JSAPI_Public_Module_Toolbar_Email_Button":["changeFormat"],
"Fine-Design_JSAPI_Form_Component_Tab":["showCardByIndex", "showCardByIndex", "getShowIndex", "setTitleVisible"]
}

8
designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java

@ -474,14 +474,6 @@ public abstract class XLayoutContainer extends XBorderStyleWidgetCreator impleme
return 0;
}
/**
* 切换到非添加状态
*
* @param designer 表单设计器
*/
public void stopAddingState(FormDesigner designer) {
}
/**
* 寻找最近的为自适应布局的父容器
*

12
designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java

@ -179,18 +179,6 @@ public class XWCardMainBorderLayout extends XWBorderLayout {
}
}
/**
* 切换到非添加状态
*
* @return designer 表单设计器
*/
@Override
public void stopAddingState(FormDesigner designer){
designer.stopAddingState();
return;
}
/**
* 添加card区域
*

9
designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java

@ -187,15 +187,6 @@ public class XWCardTagLayout extends XWHorizontalBoxLayout {
return DEFAULT_NAME;
}
/**
* 切换到非添加状态
*
* @return designer 表单设计器
*/
@Override
public void stopAddingState(FormDesigner designer) {
designer.stopAddingState();
}
//新增时去tabFitLayout名字中最大的Index+1,防止重名
private int getTabNameIndex() {

13
designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTitleLayout.java

@ -166,18 +166,7 @@ public class XWCardTitleLayout extends XWBorderLayout {
XWCardTagLayout xwCardTagLayout = (XWCardTagLayout) this.getComponent(0);
this.addTagPart(xwCardTagLayout);
}
/**
* 切换到非添加状态
*
* @return designer 表单设计器
*/
@Override
public void stopAddingState(FormDesigner designer){
designer.stopAddingState();
return;
}
/**
* 该布局隐藏无需对边框进行操作
* @param border 边框

85
designer-form/src/main/java/com/fr/design/fit/FormFitAttrAction.java

@ -0,0 +1,85 @@
package com.fr.design.fit;
import com.fr.design.actions.JTemplateAction;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.UIDialog;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JForm;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.report.fit.FormFitAttrModelType;
import com.fr.form.main.Form;
import com.fr.report.fit.FitProvider;
import com.fr.report.fit.ReportFitAttr;
import javax.swing.KeyStroke;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
public class FormFitAttrAction extends JTemplateAction {
private static final MenuKeySet REPORT_FIT_ATTR = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'T';
}
@Override
public String getMenuName() {
return Toolkit.i18nText("Fine-Designer_PC_Fit_Attr");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
public FormFitAttrAction(JTemplate jTemplate) {
super(jTemplate);
initMenuStyle();
}
private void initMenuStyle() {
this.setMenuKeySet(REPORT_FIT_ATTR);
this.setName(getMenuKeySet().getMenuKeySetName() + "...");
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon("/com/fr/design/images/reportfit/fit");
}
/**
* Action触发事件
*
* @param e 事件
*/
@Override
public void actionPerformed(ActionEvent e) {
final JTemplate jwb = getEditingComponent();
if (jwb == null || !(jwb.getTarget() instanceof Form)) {
return;
}
JForm jForm = (JForm) jwb;
Form wbTpl = jForm.getTarget();
ReportFitAttr fitAttr = wbTpl.getReportFitAttr();
FormFitAttrPane formFitAttrPane = new FormFitAttrPane(jForm, FormFitAttrModelType.parse(wbTpl));
showReportFitDialog(fitAttr, jwb, wbTpl, formFitAttrPane);
}
private void showReportFitDialog(ReportFitAttr fitAttr, final JTemplate jwb, final FitProvider wbTpl, final BasicBeanPane<ReportFitAttr> attrPane) {
attrPane.populateBean(fitAttr);
UIDialog dialog = attrPane.showWindowWithCustomSize(DesignerContext.getDesignerFrame(), new DialogActionAdapter() {
@Override
public void doOk() {
fireEditingOk(jwb, wbTpl, attrPane.updateBean(), fitAttr);
}
}, new Dimension(660, 600));
dialog.setVisible(true);
}
private void fireEditingOk(final JTemplate jwb, final FitProvider wbTpl, ReportFitAttr newReportFitAttr, ReportFitAttr oldReportFitAttr) {
wbTpl.setReportFitAttr(newReportFitAttr);
jwb.fireTargetModified();
}
}

377
designer-form/src/main/java/com/fr/design/fit/FormFitAttrPane.java

@ -0,0 +1,377 @@
package com.fr.design.fit;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XOccupiedLayout;
import com.fr.design.designer.creator.XWAbsoluteBodyLayout;
import com.fr.design.designer.creator.XWFitLayout;
import com.fr.design.designer.creator.XWScaleLayout;
import com.fr.design.designer.properties.items.FRLayoutTypeItems;
import com.fr.design.designer.properties.items.Item;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.FormDesigner;
import com.fr.design.mainframe.FormSelectionUtils;
import com.fr.design.mainframe.JForm;
import com.fr.design.mainframe.WidgetPropertyPane;
import com.fr.design.report.fit.FitType;
import com.fr.design.report.fit.FormFitAttrModelType;
import com.fr.design.report.fit.FormFitConfigPane;
import com.fr.design.report.fit.ReportFitConfigPane;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.form.main.Form;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WAbsoluteBodyLayout;
import com.fr.form.ui.container.WAbsoluteLayout;
import com.fr.form.ui.container.WBodyLayoutType;
import com.fr.form.ui.container.WFitLayout;
import com.fr.form.ui.container.WSortLayout;
import com.fr.general.ComparatorUtils;
import com.fr.general.act.BorderPacker;
import com.fr.log.FineLoggerFactory;
import com.fr.report.fit.ReportFitAttr;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import static com.fr.design.i18n.Toolkit.i18nText;
import static javax.swing.JOptionPane.*;
public class FormFitAttrPane extends BasicBeanPane<ReportFitAttr> {
private UIComboBox layoutComboBox;
private UIComboBox scaleComboBox;
private FormFitAttrModelType fitAttrModelType;
protected UIComboBox itemChoose;
private JForm jForm;
private ReportFitConfigPane fitConfigPane;
public FormFitAttrPane(JForm jForm, FormFitAttrModelType fitAttrModelType) {
this.fitAttrModelType = fitAttrModelType;
this.jForm = jForm;
initComponents();
}
private void initComponents() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.setBorder(BorderFactory.createEmptyBorder(12, 5, 0, 5));
this.add(createReportFitSettingPane(), BorderLayout.CENTER);
this.add(createReportLayoutSettingPane(), BorderLayout.NORTH);
}
private JPanel createReportLayoutSettingPane() {
JPanel jPanel = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Form_PC_Fit_Config_Layout"));
jPanel.add(createAreaScalePane(), BorderLayout.CENTER);
jPanel.setPreferredSize(new Dimension(640, 84));
return jPanel;
}
protected String[] getItemNames() {
return new String[]{Toolkit.i18nText("Fine-Design_Report_Using_Server_Report_View_Settings"),
Toolkit.i18nText("Fine-Design_Report_I_Want_To_Set_Single")};
}
private JPanel createReportFitSettingPane() {
JPanel jPanel = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Form_PC_Fit_Config_Content_Attr"));
JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
jPanel.add(contentPane, BorderLayout.CENTER);
UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Form_PC_Fit_Config_Settings"));
label.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));
contentPane.add(label, BorderLayout.WEST);
label.setPreferredSize(new Dimension(100, 0));
label.setVerticalAlignment(SwingConstants.TOP);
itemChoose = new UIComboBox(getItemNames());
itemChoose.setPreferredSize(new Dimension(160, 20));
Form form = jForm.getTarget();
itemChoose.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
if (isTemplateSingleSet()) {
if (form != null) {
ReportFitAttr fitAttr = form.getReportFitAttr();
populate(fitAttr);
}
} else {
populate(fitAttrModelType.getFitAttrModel().getGlobalReportFitAttr());
}
}
}
});
JPanel centerPane = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true);
centerPane.add(itemChoose);
centerPane.add(fitConfigPane = new FormFitConfigPane(this.fitAttrModelType.getFitAttrModel()));
contentPane.add(centerPane, BorderLayout.CENTER);
return jPanel;
}
public void populate(ReportFitAttr reportFitAttr) {
if (reportFitAttr == null) {
reportFitAttr = fitAttrModelType.getFitAttrModel().getGlobalReportFitAttr();
}
this.setEnabled(isTemplateSingleSet());
fitConfigPane.populateBean(reportFitAttr);
}
public ReportFitAttr updateBean() {
updateLayoutType();
if (!isTemplateSingleSet()) {
return null;
} else {
return fitConfigPane.updateBean();
}
}
private void updateLayoutType() {
XLayoutContainer xLayoutContainer = this.jForm.getRootComponent();
if (xLayoutContainer == null || !xLayoutContainer.acceptType(XWFitLayout.class)) {
return;
}
XWFitLayout xwFitLayout = (XWFitLayout) xLayoutContainer;
WFitLayout wFitLayout = xwFitLayout.toData();
int state = layoutComboBox.getSelectedIndex();
WBodyLayoutType selectType = WBodyLayoutType.parse(state);
if (selectType != wFitLayout.getBodyLayoutType()) {
wFitLayout.setLayoutType(selectType);
//从自适应布局切换到绝对布局
if (selectType == WBodyLayoutType.ABSOLUTE) {
switchLayoutFromFit2Absolute(xwFitLayout);
} else {
//从绝对布局切换到自适应布局
switchLayoutFromAbsolute2Fit(xwFitLayout);
}
}
wFitLayout.setCompatibleScaleAttr(fitAttrModelType.parseScaleAttrFromShowIndex(this.scaleComboBox.getSelectedIndex(), wFitLayout.getBodyLayoutType()));
}
private void switchLayoutFromFit2Absolute(XWFitLayout xWFitLayout) {
try {
WFitLayout layout = xWFitLayout.toData();
WAbsoluteBodyLayout wAbsoluteBodyLayout = new WAbsoluteBodyLayout("body");
wAbsoluteBodyLayout.setCompState(WAbsoluteLayout.STATE_FIXED);
// 切换布局类型时,保留body背景样式
wAbsoluteBodyLayout.setBorderStyleFollowingTheme(layout.isBorderStyleFollowingTheme());
wAbsoluteBodyLayout.setBorderStyle((BorderPacker) (layout.getBorderStyle().clone()));
Component[] components = xWFitLayout.getComponents();
Rectangle[] backupBounds = getBackupBoundsFromFitLayout(xWFitLayout);
xWFitLayout.removeAll();
layout.resetStyle();
XWAbsoluteBodyLayout xwAbsoluteBodyLayout = xWFitLayout.getBackupParent() == null ? new XWAbsoluteBodyLayout(wAbsoluteBodyLayout, new Dimension(0, 0)) : (XWAbsoluteBodyLayout) xWFitLayout.getBackupParent();
xWFitLayout.setFixLayout(false);
xWFitLayout.getLayoutAdapter().addBean(xwAbsoluteBodyLayout, 0, 0);
for (int i = 0; i < components.length; i++) {
XCreator xCreator = (XCreator) components[i];
xCreator.setBounds(backupBounds[i]);
//部分控件被ScaleLayout包裹着,绝对布局里面要放出来
if (xCreator.acceptType(XWScaleLayout.class)) {
if (xCreator.getComponentCount() > 0 && ((XCreator) xCreator.getComponent(0)).shouldScaleCreator()) {
Component component = xCreator.getComponent(0);
component.setBounds(xCreator.getBounds());
}
}
if (!xCreator.acceptType(XOccupiedLayout.class)) {
xwAbsoluteBodyLayout.add(xCreator);
}
}
copyLayoutAttr(layout, xwAbsoluteBodyLayout.toData());
xWFitLayout.setBackupParent(xwAbsoluteBodyLayout);
FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner();
formDesigner.getSelectionModel().setSelectedCreators(
FormSelectionUtils.rebuildSelection(xWFitLayout, new Widget[]{wAbsoluteBodyLayout}));
if (xwAbsoluteBodyLayout.toData() != null) {
xwAbsoluteBodyLayout.toData().setBorderStyleFollowingTheme(wAbsoluteBodyLayout.isBorderStyleFollowingTheme());
xwAbsoluteBodyLayout.toData().setBorderStyle(wAbsoluteBodyLayout.getBorderStyle());
}
xwAbsoluteBodyLayout.refreshStylePreviewEffect();
if (xWFitLayout.toData() != null) {
xWFitLayout.toData().resetStyle();
}
xWFitLayout.refreshStylePreviewEffect();
formDesigner.switchBodyLayout(xwAbsoluteBodyLayout);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
private Rectangle[] getBackupBoundsFromFitLayout(XWFitLayout xWFitLayout) {
int count = xWFitLayout.getComponentCount();
Rectangle[] rectangles = new Rectangle[count];
for (int i = 0; i < count; i++) {
rectangles[i] = xWFitLayout.getComponent(i).getBounds();
}
return rectangles;
}
protected void copyLayoutAttr(WSortLayout srcLayout, WSortLayout destLayout) {
destLayout.clearListeners();
destLayout.clearMobileWidgetList();
for (int i = 0, len = srcLayout.getMobileWidgetListSize(); i < len; i++) {
destLayout.addMobileWidget(srcLayout.getMobileWidget(i));
}
destLayout.setSorted(true);
for (int i = 0, len = srcLayout.getListenerSize(); i < len; i++) {
destLayout.addListener(srcLayout.getListener(i));
}
srcLayout.clearListeners();
srcLayout.clearMobileWidgetList();
}
private void switchLayoutFromAbsolute2Fit(XWFitLayout xwFitLayout) {
XWAbsoluteBodyLayout xwAbsoluteBodyLayout = getAbsoluteBodyLayout(xwFitLayout);
if (xwAbsoluteBodyLayout == null) {
return;
}
WAbsoluteBodyLayout layout = xwAbsoluteBodyLayout.toData();
WFitLayout wFitLayout = xwFitLayout.toData();
wFitLayout.resetStyle();
xwFitLayout.switch2FitBodyLayout(xwAbsoluteBodyLayout);
// 切换布局类型时,保留body背景样式
if (wFitLayout != null) {
wFitLayout.setBorderStyleFollowingTheme(layout.isBorderStyleFollowingTheme());
wFitLayout.setBorderStyle(layout.getBorderStyle());
}
copyLayoutAttr(layout, xwFitLayout.toData());
copyLayoutAttr(layout, xwFitLayout.toData());
xwFitLayout.refreshStylePreviewEffect();
}
private XWAbsoluteBodyLayout getAbsoluteBodyLayout(XWFitLayout xwFitLayout) {
if (xwFitLayout != null && xwFitLayout.getComponentCount() > 0) {
Component component = xwFitLayout.getComponent(0);
if (component instanceof XWAbsoluteBodyLayout) {
return (XWAbsoluteBodyLayout) component;
}
}
return null;
}
private JPanel createAreaScalePane() {
initLayoutComboBox();
UILabel layoutTypeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type"));
UILabel scaleModeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_PC_Fit_Config_Scale_Setting"));
Component[][] components = new Component[][]{
{layoutTypeLabel, layoutComboBox},
{scaleModeLabel, scaleComboBox}
};
JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(components,
TableLayoutHelper.FILL_LASTCOLUMN, 20, IntervalConstants.INTERVAL_L1);
JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
containerPane.add(contentPane, BorderLayout.CENTER);
return containerPane;
}
public void initLayoutComboBox() {
Item[] items = FRLayoutTypeItems.ITEMS;
DefaultComboBoxModel model = new DefaultComboBoxModel();
for (Item item : items) {
model.addElement(item);
}
scaleComboBox = new UIComboBox(model);
scaleComboBox.setModel(new DefaultComboBoxModel(fitAttrModelType.getFitLayoutScaleAttr()));
layoutComboBox = new UIComboBox(model);
layoutComboBox.setPreferredSize(new Dimension(160, 20));
scaleComboBox.setPreferredSize(new Dimension(160, 20));
WFitLayout wFitLayout = jForm.getTarget().getWFitLayout();
layoutComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int selectIndex = layoutComboBox.getSelectedIndex();
if (selectIndex == 0) {
if (wFitLayout.getBodyLayoutType() == WBodyLayoutType.ABSOLUTE) {
int selVal = FineJOptionPane.showConfirmDialog(
FormFitAttrPane.this,
Toolkit.i18nText("Fine-Design_Form_Layout_Switch_Tip"),
Toolkit.i18nText("Fine-Design_Basic_Alert"),
OK_CANCEL_OPTION,
WARNING_MESSAGE
);
if (OK_OPTION != selVal) {
layoutComboBox.setSelectedIndex(1);
return;
}
}
scaleComboBox.setModel(new DefaultComboBoxModel(fitAttrModelType.getFitLayoutScaleAttr()));
} else {
scaleComboBox.setModel(new DefaultComboBoxModel(fitAttrModelType.getAbsoluteLayoutSaleAttr()));
}
scaleComboBox.setSelectedIndex(0);
}
});
scaleComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
WBodyLayoutType selectBodyType = WBodyLayoutType.parse(layoutComboBox.getSelectedIndex());
int state = fitAttrModelType.parseScaleAttrFromShowIndex(scaleComboBox.getSelectedIndex(), selectBodyType);
fitConfigPane.refreshPreviewJPanel(FitType.parseByFitState(state));
}
});
}
@Override
public void populateBean(ReportFitAttr reportFitAttr) {
WFitLayout wFitLayout = jForm.getTarget().getWFitLayout();
layoutComboBox.setSelectedIndex(wFitLayout.getBodyLayoutType().getTypeValue());
scaleComboBox.setSelectedIndex(fitAttrModelType.getScaleAttrShowIndex(wFitLayout));
if (reportFitAttr == null) {
itemChoose.setSelectedItem(Toolkit.i18nText("Fine-Design_Report_Using_Server_Report_View_Settings"));
} else {
itemChoose.setSelectedItem(Toolkit.i18nText("Fine-Design_Report_I_Want_To_Set_Single"));
}
if (reportFitAttr == null) {
reportFitAttr = fitAttrModelType.getFitAttrModel().getGlobalReportFitAttr();
}
setEnabled(isTemplateSingleSet());
fitConfigPane.populateBean(reportFitAttr);
}
private boolean isTemplateSingleSet() {
return ComparatorUtils.equals(Toolkit.i18nText("Fine-Design_Report_I_Want_To_Set_Single"), itemChoose.getSelectedItem());
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
fitConfigPane.setEnabled(enabled);
}
@Override
protected String title4PopupWindow() {
return i18nText("Fine-Designer_PC_Fit_Attr");
}
}

14
designer-form/src/main/java/com/fr/design/mainframe/JForm.java

@ -14,7 +14,6 @@ import com.fr.base.vcs.DesignerMode;
import com.fr.design.DesignModelAdapter;
import com.fr.design.DesignState;
import com.fr.design.DesignerEnvManager;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.FormMobileAttrAction;
import com.fr.design.actions.TemplateParameterAction;
import com.fr.design.actions.core.WorkBookSupportable;
@ -37,7 +36,7 @@ import com.fr.design.designer.properties.FormWidgetAuthorityEditPane;
import com.fr.design.event.TargetModifiedEvent;
import com.fr.design.event.TargetModifiedListener;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.fun.FormAdaptiveConfigUIProcessor;
import com.fr.design.fit.FormFitAttrAction;
import com.fr.design.fun.PreviewProvider;
import com.fr.design.fun.PropertyItemPaneProvider;
import com.fr.design.gui.frpane.HyperlinkGroupPane;
@ -66,7 +65,6 @@ import com.fr.design.menu.ToolBarDef;
import com.fr.design.parameter.ParameterPropertyPane;
import com.fr.design.preview.FormPreview;
import com.fr.design.preview.MobilePreview;
import com.fr.design.report.fit.menupane.ReportFitAttrAction;
import com.fr.design.roleAuthority.RolesAlreadyEditedPane;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.file.FILE;
@ -597,11 +595,7 @@ public class JForm extends JTemplate<Form, FormUndoState> implements BaseJForm<F
protected ShortCut getReportFitAttrAction() {
FormAdaptiveConfigUIProcessor adaptiveConfigUI = ExtraDesignClassManager.getInstance().getSingle(FormAdaptiveConfigUIProcessor.MARK_STRING);
if (adaptiveConfigUI != null) {
return adaptiveConfigUI.getConfigShortCut(this);
}
return new ReportFitAttrAction(this);
return new FormFitAttrAction(this);
}
/**
@ -1239,4 +1233,8 @@ public class JForm extends JTemplate<Form, FormUndoState> implements BaseJForm<F
public void setDesignerUIMode(){
DesignerUIModeConfig.getInstance().setSimulateWebUIMode();
}
public XLayoutContainer getRootComponent(){
return this.formDesign.getRootComponent();
}
}

6
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetTabPane.java

@ -24,6 +24,7 @@ public class OnlineWidgetTabPane extends JPanel {
private static final String COMPONENT = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share");
private static final String COMPONENT_PACKAGE = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Package");
private static final String COMPONENT_EMBED = "COMPONENT_EMBED";
private UITabGroup headGroup;
private CardLayout cardLayout;
private JPanel centerPane;
private boolean packagePaneCreated = false;
@ -43,7 +44,7 @@ public class OnlineWidgetTabPane extends JPanel {
this.centerPane.add(new OnlineWidgetShowPane(sharableWidgets), COMPONENT);
this.centerPane.add( embedFilterShowPane = new OnlineEmbedFilterShowPane(new OnlineWidgetShowPane(sharableWidgets, OnlineWidgetSortType.SALES)), COMPONENT_EMBED);
//延迟组件包面板的初始化,防止组件面板里组件的缩略图和组件包面板里组件的缩略图一起加载
UITabGroup headGroup = new UITabGroup(new String[]{COMPONENT, COMPONENT_PACKAGE}) {
this.headGroup = new UITabGroup(new String[]{COMPONENT, COMPONENT_PACKAGE}) {
public void tabChanged(int newSelectedIndex) {
for (TabChangeListener changeListener : tabChangeListeners) {
changeListener.tabChange(newSelectedIndex);
@ -63,7 +64,7 @@ public class OnlineWidgetTabPane extends JPanel {
}
};
headGroup.setSelectedIndex(0);
this.headGroup.setSelectedIndex(0);
this.centerPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
jPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
@ -84,6 +85,7 @@ public class OnlineWidgetTabPane extends JPanel {
}
}
public void refreshPane() {
this.headGroup.setSelectedIndex(0);
this.cardLayout.show(centerPane, ComponentShareUtil.needShowEmbedFilterPane() ? COMPONENT_EMBED : COMPONENT);
}

19
designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java

@ -6,10 +6,13 @@ import com.fr.design.fun.impl.AbstractPreviewProvider;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.JForm;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.worker.WorkerManager;
import com.fr.design.worker.save.CallbackSaveWorker;
import com.fr.general.web.ParameterConstants;
import java.util.HashMap;
import java.util.Map;
import javax.swing.SwingWorker;
/**
* Created by kerry on 2020-04-23
@ -44,6 +47,22 @@ public class DeveloperPreview extends AbstractPreviewProvider {
@Override
public void onClick(JTemplate<?, ?> jt) {
super.onClick(jt);
SwingWorker worker = WorkerManager.getInstance().getWorker(jt.getRuntimeId());
if (worker instanceof CallbackSaveWorker) {
CallbackSaveWorker callbackSaveWorker = (CallbackSaveWorker) worker;
callbackSaveWorker.addSuccessCallbackBeforeLast(new Runnable() {
@Override
public void run() {
onPreview(jt);
}
});
} else if (jt.getEditingFILE().isEnvFile()) {
// 已经保存在当前工作目录了
onPreview(jt);
}
}
private void onPreview(JTemplate<?, ?> jt) {
MutilTempalteTabPane.getInstance().closeCurrentTpl();
jt.generateForBiddenTemplate();
}

110
designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteBodyLayoutDefinePane.java

@ -7,54 +7,36 @@ import com.fr.base.theme.TemplateTheme;
import com.fr.design.data.DataCreatorUI;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XWFitLayout;
import com.fr.design.designer.properties.items.FRLayoutTypeItems;
import com.fr.design.designer.properties.items.Item;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.fit.common.TemplateTool;
import com.fr.design.foldablepane.UIExpandablePane;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UIAutoChangeLineLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.style.FollowingThemePane;
import com.fr.design.gui.xpane.LayoutStylePane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.WidgetPropertyPane;
import com.fr.design.mainframe.widget.accessibles.AccessibleBodyWatermarkEditor;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.design.widget.ui.designer.component.WidgetBoundPane;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.form.ui.container.WAbsoluteBodyLayout;
import com.fr.form.ui.container.WAbsoluteLayout;
import com.fr.form.ui.container.WBodyLayoutType;
import com.fr.form.ui.container.WFitLayout;
import com.fr.general.act.BorderPacker;
import com.fr.report.core.ReportUtils;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import static javax.swing.JOptionPane.OK_CANCEL_OPTION;
import static javax.swing.JOptionPane.OK_OPTION;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
/**
* Created by ibm on 2017/8/2.
*/
public class FRAbsoluteBodyLayoutDefinePane extends FRAbsoluteLayoutDefinePane {
private static final int MAX_LABEL_WIDTH = 80;
protected FollowingThemePane themePane;
private LayoutStylePane stylePane;
private AccessibleBodyWatermarkEditor watermarkEditor;
private WidgetBoundPane boundPane;
private UIComboBox layoutCombox;
private WBodyLayoutType layoutType = WBodyLayoutType.ABSOLUTE;
public FRAbsoluteBodyLayoutDefinePane(XCreator xCreator) {
super(xCreator);
@ -62,22 +44,9 @@ public class FRAbsoluteBodyLayoutDefinePane extends FRAbsoluteLayoutDefinePane {
public void initComponent() {
initUIComboBox();
this.setLayout(FRGUIPaneFactory.createBorderLayout());
boundPane = new WidgetBoundPane(creator);
if (!TemplateTool.isCurrentEditingNewJForm()){
this.add(boundPane, BorderLayout.NORTH);
}
JPanel panel1 = FRGUIPaneFactory.createBorderLayout_S_Pane();
this.add(panel1, BorderLayout.CENTER);
UIExpandablePane scalePane = new UIExpandablePane(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Area_Scaling"),
280, 20,
createAreaScalePane()
);
panel1.add(scalePane, BorderLayout.NORTH);
UIExpandablePane advancedPane = new UIExpandablePane(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"),
280, 20,
@ -115,41 +84,15 @@ public class FRAbsoluteBodyLayoutDefinePane extends FRAbsoluteLayoutDefinePane {
}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W3, IntervalConstants.INTERVAL_L1);
watermarkPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0));
advancedContentPane.add(watermarkPane, BorderLayout.CENTER);
UIAutoChangeLineLabel tip = new UIAutoChangeLineLabel(Toolkit.i18nText("Fine-Design_Form_Body_Layout_Setting_Tip"), 216);
tip.setForeground(Color.lightGray);
advancedContentPane.add(tip, BorderLayout.SOUTH);
return advancedContentPane;
}
public JPanel createAreaScalePane() {
initLayoutComboBox();
UILabel layoutTypeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type"));
UILabel scaleModeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode"));
Component[][] components = TemplateTool.isCurrentEditingNewJForm() ? new Component[][]{
{layoutTypeLabel, layoutCombox}
} : new Component[][]{
{layoutTypeLabel, layoutCombox},
{scaleModeLabel, comboBox}
};
JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(components,
TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1);
contentPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0));
JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
containerPane.add(contentPane, BorderLayout.CENTER);
containerPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
return containerPane;
}
public void initLayoutComboBox() {
Item[] items = FRLayoutTypeItems.ITEMS;
DefaultComboBoxModel model = new DefaultComboBoxModel();
for (Item item : items) {
model.addElement(item);
}
layoutCombox = new UIComboBox(model);
layoutCombox.setSelectedIndex(1);
@Override
public void doLayout() {
super.doLayout();
}
@Override
@ -158,51 +101,14 @@ public class FRAbsoluteBodyLayoutDefinePane extends FRAbsoluteLayoutDefinePane {
}
public void populateSubPane(WAbsoluteLayout ob) {
layoutCombox.setSelectedIndex(1);
themePane.supportFollowingTheme(ob.supportThemed());
themePane.setFollowingTheme(ob.isBorderStyleFollowingTheme());
stylePane.populateBean((LayoutBorderStyle) ob.getBorderStyle());
boundPane.populate();
watermarkEditor.setValue(ReportUtils.getWatermarkAttrFromTemplate(getCurrentIOFile()));
}
public WAbsoluteBodyLayout updateSubPane() {
WAbsoluteBodyLayout layout = (WAbsoluteBodyLayout) creator.toData();
boundPane.update();
Item item = (Item) layoutCombox.getSelectedItem();
Object value = item.getValue();
int state = 0;
if (value instanceof Integer) {
state = (Integer) value;
}
if (layoutType == WBodyLayoutType.ABSOLUTE) {
((XWFitLayout) creator.getBackupParent()).toData().resetStyle();
if (state == WBodyLayoutType.FIT.getTypeValue()) {
XWFitLayout xwFitLayout = ((XWFitLayout)creator.getBackupParent());
int selVal = FineJOptionPane.showConfirmDialog(
DesignerContext.getDesignerFrame(),
Toolkit.i18nText("Fine-Design_Form_Layout_Switch_Tip"),
Toolkit.i18nText("Fine-Design_Basic_Alert"),
OK_CANCEL_OPTION,
WARNING_MESSAGE
);
if(OK_OPTION == selVal){
xwFitLayout.switch2FitBodyLayout(creator);
WFitLayout wFitLayout = xwFitLayout.toData();
// 切换布局类型时,保留body背景样式
if (wFitLayout != null) {
wFitLayout.setBorderStyleFollowingTheme(layout.isBorderStyleFollowingTheme());
wFitLayout.setBorderStyle(layout.getBorderStyle());
}
copyLayoutAttr(layout, xwFitLayout.toData());
}else {
this.layoutCombox.setSelectedIndex(1);
}
copyLayoutAttr(layout, xwFitLayout.toData());
xwFitLayout.refreshStylePreviewEffect();
}
}
layout.setBorderStyleFollowingTheme(themePane.isFollowingTheme());
layout.setBorderStyle(stylePane.updateBean());
updateWatermark();

54
designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteLayoutDefinePane.java

@ -1,30 +1,15 @@
package com.fr.design.widget.ui.designer.layout;
import com.fr.design.data.DataCreatorUI;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.properties.items.FRAbsoluteConstraintsItems;
import com.fr.design.designer.properties.items.Item;
import com.fr.design.fit.common.TemplateTool;
import com.fr.design.foldablepane.UIExpandablePane;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.form.ui.container.WAbsoluteLayout;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
/**
* Created by ibm on 2017/8/2.
*/
public class FRAbsoluteLayoutDefinePane extends AbstractFRLayoutDefinePane<WAbsoluteLayout> {
protected UIComboBox comboBox;
public FRAbsoluteLayoutDefinePane(XCreator xCreator) {
super(xCreator);
@ -34,40 +19,8 @@ public class FRAbsoluteLayoutDefinePane extends AbstractFRLayoutDefinePane<WAbso
public void initComponent() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
initUIComboBox();
JPanel thirdPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel jPanel = createThirdPane();
jPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
thirdPane.add(jPanel, BorderLayout.CENTER);
UIExpandablePane layoutExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Area_Scaling"), 280, 20, thirdPane);
if (!TemplateTool.isCurrentEditingNewJForm()){
this.add(layoutExpandablePane, BorderLayout.CENTER);
}
}
public JPanel createThirdPane() {
double f = TableLayout.FILL;
double p = TableLayout.PREFERRED;
double[] rowSize = {p};
double[] columnSize = {p, f};
int[][] rowCount = {{1, 1}};
Component[][] components = new Component[][]{
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode")), comboBox},
};
JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1);
// panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
return panel;
}
public void initUIComboBox() {
Item[] items = FRAbsoluteConstraintsItems.ITEMS;
DefaultComboBoxModel model = new DefaultComboBoxModel();
for (Item item : items) {
model.addElement(item);
}
comboBox = new UIComboBox(model);
}
@Override
public String title4PopupWindow() {
@ -77,20 +30,17 @@ public class FRAbsoluteLayoutDefinePane extends AbstractFRLayoutDefinePane<WAbso
@Override
public void populateBean(WAbsoluteLayout ob) {
populateSubPane(ob);
comboBox.setSelectedIndex(ob.getCompState());
}
@Override
public WAbsoluteLayout updateBean() {
WAbsoluteLayout wAbsoluteLayout = updateSubPane();
wAbsoluteLayout.setCompState(comboBox.getSelectedIndex());
return wAbsoluteLayout;
return updateSubPane();
}
public WAbsoluteLayout updateSubPane() {
return (WAbsoluteLayout)creator.toData();
return (WAbsoluteLayout) creator.toData();
}
public void populateSubPane(WAbsoluteLayout ob) {

118
designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRFitLayoutDefinePane.java

@ -9,16 +9,10 @@ import com.fr.design.designer.IntervalConstants;
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XOccupiedLayout;
import com.fr.design.designer.creator.XWAbsoluteBodyLayout;
import com.fr.design.designer.creator.XWFitLayout;
import com.fr.design.designer.creator.XWScaleLayout;
import com.fr.design.designer.properties.items.FRFitConstraintsItems;
import com.fr.design.designer.properties.items.FRLayoutTypeItems;
import com.fr.design.designer.properties.items.Item;
import com.fr.design.fit.common.TemplateTool;
import com.fr.design.foldablepane.UIExpandablePane;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UIAutoChangeLineLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.gui.style.FollowingThemePane;
@ -35,13 +29,9 @@ import com.fr.design.widget.FRWidgetFactory;
import com.fr.design.widget.ui.designer.component.PaddingBoundPane;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WAbsoluteBodyLayout;
import com.fr.form.ui.container.WAbsoluteLayout;
import com.fr.form.ui.container.WBodyLayoutType;
import com.fr.form.ui.container.WFitLayout;
import com.fr.general.ComparatorUtils;
import com.fr.general.act.BorderPacker;
import com.fr.log.FineLoggerFactory;
import com.fr.report.core.ReportUtils;
import javax.swing.*;
@ -51,11 +41,8 @@ import java.awt.*;
* Created by ibm on 2017/8/2.
*/
public class FRFitLayoutDefinePane extends AbstractFRLayoutDefinePane<WFitLayout> {
private static final int ADAPT_LABEL_MAX_WIDTH = 80;
private XWFitLayout xWFitLayout;
private WFitLayout wFitLayout;
private UIComboBox layoutComboBox;
private UIComboBox adaptComboBox;
private UISpinner componentIntervel;
private PaddingBoundPane paddingBound;
private FollowingThemePane themePane;
@ -119,11 +106,7 @@ public class FRFitLayoutDefinePane extends AbstractFRLayoutDefinePane<WFitLayout
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_WaterMark")), watermarkEditor}
}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W3, IntervalConstants.INTERVAL_L1);
waterMarkPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
contentPane1.add(waterMarkPane, BorderLayout.NORTH);
paddingBound = new PaddingBoundPane();
contentPane1.add(paddingBound, BorderLayout.CENTER);
contentPane1.add(waterMarkPane, BorderLayout.CENTER);
return contentPane0;
}
@ -137,22 +120,12 @@ public class FRFitLayoutDefinePane extends AbstractFRLayoutDefinePane<WFitLayout
public JPanel createLayoutPane() {
JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
layoutComboBox = initUIComboBox(FRLayoutTypeItems.ITEMS);
adaptComboBox = initUIComboBox(FRFitConstraintsItems.ITEMS);
JPanel adaptComboBoxPane = UIComponentUtils.wrapWithBorderLayoutPane(adaptComboBox);
componentIntervel = new UISpinner(0, Integer.MAX_VALUE, 1, 0, false);
JPanel componentIntervelPane = UIComponentUtils.wrapWithBorderLayoutPane(componentIntervel);
UILabel adaptLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Component_Scale"));
UILabel intervalLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Component_Interval"));
Component[][] components = TemplateTool.isCurrentEditingNewJForm() ? new Component[][]{
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")), layoutComboBox},
{intervalLabel, componentIntervelPane}
} : new Component[][]{
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")), layoutComboBox},
{adaptLabel, adaptComboBoxPane},
Component[][] components = new Component[][]{
{intervalLabel, componentIntervelPane}
};
@ -160,19 +133,17 @@ public class FRFitLayoutDefinePane extends AbstractFRLayoutDefinePane<WFitLayout
components,
TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1);
contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
containerPane.add(contentPane, BorderLayout.CENTER);
containerPane.add(contentPane, BorderLayout.NORTH);
paddingBound = new PaddingBoundPane();
containerPane.add(paddingBound, BorderLayout.CENTER);
UIAutoChangeLineLabel tip = new UIAutoChangeLineLabel(Toolkit.i18nText("Fine-Design_Form_Body_Layout_Setting_Tip"),216);
tip.setForeground(Color.lightGray);
containerPane.add(tip, BorderLayout.SOUTH);
return containerPane;
}
public UIComboBox initUIComboBox(Item[] items) {
DefaultComboBoxModel model = new DefaultComboBoxModel();
for (Item item : items) {
model.addElement(item);
}
return new UIComboBox(model);
}
@Override
@ -193,8 +164,6 @@ public class FRFitLayoutDefinePane extends AbstractFRLayoutDefinePane<WFitLayout
paddingBound.populate(ob);
paddingBound.setEnabled(supportModifyInterval());
layoutComboBox.setSelectedIndex(ob.getBodyLayoutType().getTypeValue());
adaptComboBox.setSelectedIndex(ob.getCompState());
componentIntervel.setValue(ob.getCompInterval());
componentIntervel.setEnabled(supportModifyInterval());
themePane.supportFollowingTheme(ob.supportThemed());
@ -224,67 +193,6 @@ public class FRFitLayoutDefinePane extends AbstractFRLayoutDefinePane<WFitLayout
layout.setBorderStyle(borderStyle);
}
updateWatermark();
Item item = (Item) layoutComboBox.getSelectedItem();
Object value = item.getValue();
int state = 0;
if (value instanceof Integer) {
state = (Integer) value;
}
//todo 验证下
layout.setLayoutType(WBodyLayoutType.parse(state));
layout.setCompState(adaptComboBox.getSelectedIndex());
try {
// 自适应布局切换到绝对布局
if (state == WBodyLayoutType.ABSOLUTE.getTypeValue()) {
WAbsoluteBodyLayout wAbsoluteBodyLayout = new WAbsoluteBodyLayout("body");
wAbsoluteBodyLayout.setCompState(WAbsoluteLayout.STATE_FIXED);
// 切换布局类型时,保留body背景样式
wAbsoluteBodyLayout.setBorderStyleFollowingTheme(layout.isBorderStyleFollowingTheme());
wAbsoluteBodyLayout.setBorderStyle((BorderPacker) (layout.getBorderStyle().clone()));
Component[] components = xWFitLayout.getComponents();
Rectangle[] backupBounds = getBackupBoundsFromFitLayout();
xWFitLayout.removeAll();
layout.resetStyle();
XWAbsoluteBodyLayout xwAbsoluteBodyLayout = xWFitLayout.getBackupParent() == null ? new XWAbsoluteBodyLayout(wAbsoluteBodyLayout, new Dimension(0, 0)) : (XWAbsoluteBodyLayout) xWFitLayout.getBackupParent();
xWFitLayout.setFixLayout(false);
xWFitLayout.getLayoutAdapter().addBean(xwAbsoluteBodyLayout, 0, 0);
for (int i = 0; i < components.length; i++) {
XCreator xCreator = (XCreator) components[i];
xCreator.setBounds(backupBounds[i]);
//部分控件被ScaleLayout包裹着,绝对布局里面要放出来
if (xCreator.acceptType(XWScaleLayout.class)) {
if (xCreator.getComponentCount() > 0 && ((XCreator) xCreator.getComponent(0)).shouldScaleCreator()) {
Component component = xCreator.getComponent(0);
component.setBounds(xCreator.getBounds());
}
}
if (!xCreator.acceptType(XOccupiedLayout.class)){
xwAbsoluteBodyLayout.add(xCreator);
}
}
copyLayoutAttr(wFitLayout, xwAbsoluteBodyLayout.toData());
xWFitLayout.setBackupParent(xwAbsoluteBodyLayout);
FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner();
formDesigner.getSelectionModel().setSelectedCreators(
FormSelectionUtils.rebuildSelection(xWFitLayout, new Widget[]{wAbsoluteBodyLayout}));
if (xwAbsoluteBodyLayout.toData() != null) {
xwAbsoluteBodyLayout.toData().setBorderStyleFollowingTheme(wAbsoluteBodyLayout.isBorderStyleFollowingTheme());
xwAbsoluteBodyLayout.toData().setBorderStyle(wAbsoluteBodyLayout.getBorderStyle());
}
xwAbsoluteBodyLayout.refreshStylePreviewEffect();
if (xWFitLayout.toData() != null) {
xWFitLayout.toData().resetStyle();
}
xWFitLayout.refreshStylePreviewEffect();
formDesigner.switchBodyLayout(xwAbsoluteBodyLayout);
return layout;
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
int intervelValue = (int) componentIntervel.getValue();
if (xWFitLayout.canAddInterval(intervelValue)) {
// 设置完间隔后,要同步处理界面组件,容器刷新后显示出对应效果
@ -302,14 +210,6 @@ public class FRFitLayoutDefinePane extends AbstractFRLayoutDefinePane<WFitLayout
return layout;
}
private Rectangle[] getBackupBoundsFromFitLayout() {
int count = xWFitLayout.getComponentCount();
Rectangle[] rectangles = new Rectangle[count];
for (int i = 0; i < count; i++) {
rectangles[i] = xWFitLayout.getComponent(i).getBounds();
}
return rectangles;
}
private void updateWatermark() {
WatermarkAttr watermark = (WatermarkAttr) watermarkEditor.getValue();

151
designer-realize/src/main/java/com/fr/design/dscolumn/DSColumnAdvancedPane.java

@ -3,6 +3,7 @@ package com.fr.design.dscolumn;
import com.fr.base.BaseFormula;
import com.fr.data.util.SortOrder;
import com.fr.design.border.UITitledBorder;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
@ -10,10 +11,10 @@ import com.fr.design.formula.CustomVariableResolver;
import com.fr.design.formula.FormulaFactory;
import com.fr.design.formula.SortFormulaPane;
import com.fr.design.formula.UIFormula;
import com.fr.design.gui.frpane.AbstractAttrNoScrollPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.gui.itextfield.UITextField;
@ -21,6 +22,7 @@ import com.fr.design.gui.style.TextFormatPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.sort.celldscolumn.CellDSColumnSortPane;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.report.cell.CellElement;
import com.fr.report.cell.TemplateCellElement;
@ -28,19 +30,11 @@ import com.fr.report.cell.cellattr.CellExpandAttr;
import com.fr.report.cell.cellattr.core.group.DSColumn;
import com.fr.report.cell.cellattr.core.group.SelectCount;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import static com.fr.report.cell.cellattr.core.group.FilterTypeEnum.BOTTOM;
import static com.fr.report.cell.cellattr.core.group.FilterTypeEnum.SPECIFY;
@ -64,8 +58,19 @@ public class DSColumnAdvancedPane extends BasicPane {
}
public DSColumnAdvancedPane(int setting) {
this.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
this.setLayout(FRGUIPaneFactory.createBorderLayout());
initContentPane(setting);
initScrollPane();
}
private void initScrollPane() {
ScrollPane scrollPane = new ScrollPane(contentPane);
this.add(scrollPane);
}
private void initContentPane(int setting) {
contentPane = new JPanel();
contentPane.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
contentPane.setLayout(FRGUIPaneFactory.createBorderLayout());
sortPane = new SortPane();
sortPane.setBorder(UITitledBorder.createBorderWithTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Sort_Sort_Order")));
@ -135,7 +140,7 @@ public class DSColumnAdvancedPane extends BasicPane {
TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED};
double[] columnSize = {TableLayout.FILL};
this.add(TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize), BorderLayout.CENTER);
contentPane.add(TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize), BorderLayout.CENTER);
}
@Override
@ -148,7 +153,7 @@ public class DSColumnAdvancedPane extends BasicPane {
return;
}
sortPane.populate(cellElement);
sortPane.populateBean(cellElement);
valuePane.populate(cellElement);
formatAttrPane.populate(cellElement);
@ -198,7 +203,7 @@ public class DSColumnAdvancedPane extends BasicPane {
return;
}
sortPane.update(cellElement);
sortPane.updateBean(cellElement);
valuePane.update(cellElement);
formatAttrPane.update(cellElement);
@ -234,66 +239,25 @@ public class DSColumnAdvancedPane extends BasicPane {
}
}
private static class SortPane extends SortFormulaPane {
private CellElement cellElement;
private static class ScrollPane extends UIScrollPane {
ScrollPane(Component component) {
super(component);
this.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
}
@Override
public void formulaAction() {
if (cellElement == null) {
return;
}
Object value = cellElement.getValue();
if (value == null || !(value instanceof DSColumn)) {
return;
}
String[] displayNames = DesignTableDataManager.getSelectedColumnNames(
DesignTableDataManager.getEditingTableDataSource(), ((DSColumn) value).getDSName());
showFormulaDialog(displayNames);
public Dimension getPreferredSize() {
return new Dimension(DSColumnPane.DEFAULT_DIMENSION.width - 20, DSColumnPane.DEFAULT_DIMENSION.height - 100);
}
}
void populate(CellElement cellElement) {
if (cellElement == null) {
return;
}
this.cellElement = cellElement;
Object value = cellElement.getValue();
if (value == null || !(value instanceof DSColumn)) {
return;
}
DSColumn dSColumn = (DSColumn) value;
int sort = dSColumn.getOrder();
this.sortOrderComboBox.setSortOrder(new SortOrder(sort));
String sortFormula = dSColumn.getSortFormula();
sortFormulaTextField.setText(sortFormula);
private static class SortPane extends CellDSColumnSortPane {
SortPane() {
this.setLayout(new FlowLayout(FlowLayout.LEFT));
}
public void update(CellElement cellElement) {
if (cellElement == null) {
return;
}
Object value = cellElement.getValue();
if (value == null || !(value instanceof DSColumn)) {
return;
}
DSColumn dSColumn = (DSColumn) (cellElement.getValue());
dSColumn.setOrder(this.sortOrderComboBox.getSortOrder().getOrder());
//lance:sort formula
String sText = null;
if (!(sortFormulaTextField.getText() == null || sortFormulaTextField.getText().trim().equals("") || sortFormulaTextField.getText().trim().equals("$$$"))) {
sText = new String(sortFormulaTextField.getText());
}
if (!(sText == null || sText.length() < 1)) {
dSColumn.setSortFormula(sText);
} else {
dSColumn.setSortFormula(null);
}
protected boolean needSortHeaderPane() {
return false;
}
}
@ -548,11 +512,11 @@ public class DSColumnAdvancedPane extends BasicPane {
}
}
public static class ReLayoutTextFormatPane extends TextFormatPane {
public static class FormatAttrPane extends TextFormatPane {
protected void initLayout() {
JComponent[][] components = new JComponent[][] { {typeComboBox, textField, roundingBox} };
double[] rowSize = new double[] { TableLayout.FILL };
JComponent[][] components = new JComponent[][]{{typeComboBox, textField, roundingBox}};
double[] rowSize = new double[]{TableLayout.FILL};
double[] columnSize = {TableLayout.PREFERRED, 200, TableLayout.PREFERRED};
JPanel settingPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, 4, 0);
@ -578,45 +542,6 @@ public class DSColumnAdvancedPane extends BasicPane {
}
}
public static class FormatAttrPane extends AbstractAttrNoScrollPane {
private TextFormatPane formatPane;
@Override
protected JPanel createContentPane() {
this.formatPane = new ReLayoutTextFormatPane();
return this.formatPane;
}
@Override
public Dimension getPreferredSize() {
if (formatPane == null) {
return super.getPreferredSize();
}
return formatPane.getPreferredSize();
}
protected void initContentPane() {
leftContentPane = createContentPane();
if (leftContentPane != null) {
leftContentPane.setBorder(BorderFactory.createEmptyBorder());
this.add(leftContentPane, BorderLayout.CENTER);
}
}
public void populate(CellElement cellElement) {
if (cellElement != null && formatPane != null) {
formatPane.populateBean(cellElement.getStyle());
}
}
public void update(CellElement cellElement) {
if (cellElement != null && formatPane != null) {
cellElement.setStyle(formatPane.update(cellElement.getStyle()));
}
}
}
private void checkButtonEnabled() {
if (useMultiplyNumCheckBox.isSelected()) {
multiNumSpinner.setEnabled(true);

2
designer-realize/src/main/java/com/fr/design/javascript/ListenerEditPane.java

@ -89,7 +89,7 @@ public class ListenerEditPane extends BasicBeanPane<Listener> {
card = new CardLayout();
hyperlinkPane = FRGUIPaneFactory.createCardLayout_S_Pane();
hyperlinkPane.setLayout(card);
JavaScriptImplPane javaScriptPane = new JavaScriptImplPane(defaultArgs);
JavaScriptImplPane javaScriptPane = new JavaScriptImplPane(defaultArgs,true);
hyperlinkPane.add(JS, javaScriptPane);
// 提交入库
List dbManiList = new ArrayList();

114
designer-realize/src/main/java/com/fr/design/mainframe/cell/AbstractDSCellEditorPane.java

@ -1,17 +1,7 @@
package com.fr.design.mainframe.cell;
import com.fr.design.gui.iscrollbar.UIScrollBar;
import com.fr.design.mainframe.CellElementPropertyPane;
import com.fr.quickeditor.cellquick.layout.CellElementBarLayout;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import com.fr.design.gui.frpane.AttributeChangeListener;
import com.fr.design.mainframe.AbstractAttrPane;
/**
* 右侧单元格元素面板抽象类
@ -20,26 +10,9 @@ import java.awt.event.MouseWheelListener;
* @version 2017年7月25日
* @since 9.0
*/
public abstract class AbstractDSCellEditorPane extends JPanel {
/**
* 滚动条相关配置
*/
private static final int MAXVALUE = 100;
private static final int TITLE_HEIGHT = 95;
private static final int CONTENT_PANE_WIDTH_GAP = 3;
private static final int SCROLLBAR_WIDTH = 7;
private static final int MOUSE_WHEEL_SPEED = 5;
private int maxHeight = 280;
private JPanel leftContentPane;
private UIScrollBar scrollBar;
protected abstract JPanel createContentPane();
public abstract class AbstractDSCellEditorPane extends AbstractAttrPane {
public abstract String getIconPath();
public abstract String title4PopupWindow();
private static final int FIXED_HEIGHT = 40;
/**
* 从面板拿数据保存
@ -51,78 +24,19 @@ public abstract class AbstractDSCellEditorPane extends JPanel {
*/
public abstract void populate();
protected void createScrollPane() {
leftContentPane = this.createContentPane();
this.prepareScrollBar();
leftContentPane.setBorder(BorderFactory.createMatteBorder(10, 10, 0, 0, this.getBackground()));
this.setLayout(new CellElementBarLayout(leftContentPane) {
@Override
public void layoutContainer(Container parent) {
maxHeight = CellElementPropertyPane.getInstance().getHeight() - TITLE_HEIGHT;
int beginY;
if ((MAXVALUE - scrollBar.getVisibleAmount()) == 0) {
beginY = 0;
} else {
int preferredHeight = leftContentPane.getPreferredSize().height;
int value = scrollBar.getValue();
beginY = value * (preferredHeight - maxHeight) / (MAXVALUE - scrollBar.getVisibleAmount());
}
int width = parent.getWidth();
int height = parent.getHeight();
if (leftContentPane.getPreferredSize().height > maxHeight) {
leftContentPane.setBounds(0, -beginY, width - SCROLLBAR_WIDTH - CONTENT_PANE_WIDTH_GAP, height + beginY);
scrollBar.setBounds(width - SCROLLBAR_WIDTH - CONTENT_PANE_WIDTH_GAP, 0, SCROLLBAR_WIDTH + CONTENT_PANE_WIDTH_GAP, height);
} else {
leftContentPane.setBounds(0, 0, width - SCROLLBAR_WIDTH - CONTENT_PANE_WIDTH_GAP, height);
}
}
});
this.add(scrollBar);
this.add(leftContentPane);
}
private void prepareScrollBar() {
scrollBar = new UIScrollBar(UIScrollBar.VERTICAL) {
@Override
public int getVisibleAmount() {
int preferredHeight = leftContentPane.getPreferredSize().height;
int e = MAXVALUE * (maxHeight) / preferredHeight;
setVisibleAmount(e);
return e;
}
@Override
public int getMaximum() {
return MAXVALUE;
}
};
scrollBar.addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
doLayout();
}
});
this.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
int value = scrollBar.getValue();
value += MOUSE_WHEEL_SPEED * e.getWheelRotation();
scrollBar.setValue(value);
doLayout();
}
});
scrollBar.setPreferredSize(new Dimension(SCROLLBAR_WIDTH + CONTENT_PANE_WIDTH_GAP, this.getHeight()));
scrollBar.setBlockIncrement(SCROLLBAR_WIDTH + CONTENT_PANE_WIDTH_GAP);
scrollBar.setBorder(BorderFactory.createMatteBorder(0, CONTENT_PANE_WIDTH_GAP, 0, 0, this.getBackground()));
}
/**
* 释放tc
*/
protected abstract void release();
protected abstract AttributeChangeListener getAttributeChangeListener();
public void addAttributeChangeListener() {
this.addAttributeChangeListener(getAttributeChangeListener());
}
protected int getMaxHeight() {
return Math.max(super.getMaxHeight() - FIXED_HEIGHT, 0);
}
}

20
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellExpandAttrPane.java

@ -4,7 +4,6 @@ import com.fr.design.constants.LayoutConstants;
import com.fr.design.constants.UIConstants;
import com.fr.design.expand.ExpandLeftFatherPane;
import com.fr.design.expand.ExpandUpFatherPane;
import com.fr.design.expand.SortExpandAttrPane;
import com.fr.design.foldablepane.UIExpandablePane;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.icheckbox.UICheckBox;
@ -13,6 +12,7 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase;
import com.fr.design.sort.cellexpand.CellExpandSortPane;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.report.cell.TemplateCellElement;
@ -38,11 +38,11 @@ public class CellExpandAttrPane extends AbstractCellAttrPane {
private ExpandUpFatherPane rightFatherPane;
private UICheckBox horizontalExpandableCheckBox;
private UICheckBox verticalExpandableCheckBox;
private SortExpandAttrPane sortAfterExpand;
private JPanel layoutPane;
private JPanel basicPane;
private JPanel seniorPane;
private CellExpandExtraAttrPane extraPane;
private CellExpandSortPane cellExpandSortPane;
/**
@ -62,7 +62,6 @@ public class CellExpandAttrPane extends AbstractCellAttrPane {
rightFatherPane = new ExpandUpFatherPane();
horizontalExpandableCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_ExpandD_Horizontal_Extendable"));
verticalExpandableCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_ExpandD_Vertical_Extendable"));
sortAfterExpand = new SortExpandAttrPane();
initAllNames();
return layoutPane();
}
@ -81,8 +80,11 @@ public class CellExpandAttrPane extends AbstractCellAttrPane {
seniorPane = new JPanel();
basicPane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Basic"), 223, 24, basicPane());
seniorPane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Advanced"), 223, 24, seniorPane());
JPanel sortUIExpandablePane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Expend_Sort"),
223, 24, cellExpandSortPane = new CellExpandSortPane(this));
layoutPane.add(basicPane, BorderLayout.NORTH);
layoutPane.add(seniorPane, BorderLayout.CENTER);
layoutPane.add(sortUIExpandablePane, BorderLayout.SOUTH);
extraPane = CellExpandExtraAttrPane.getInstance();
@ -119,16 +121,12 @@ public class CellExpandAttrPane extends AbstractCellAttrPane {
private JPanel seniorPane() {
double f = TableLayout.FILL;
double p = TableLayout.PREFERRED;
UILabel expendSort = new UILabel(Toolkit.i18nText("Fine-Design_Report_Expend_Sort"), SwingConstants.LEFT);
JPanel expendSortPane = new JPanel(new BorderLayout());
expendSortPane.add(expendSort, BorderLayout.NORTH);
horizontalExpandableCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER);
verticalExpandableCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER);
Component[][] components = new Component[][]{
new Component[]{null, null},
new Component[]{horizontalExpandableCheckBox, null},
new Component[]{verticalExpandableCheckBox, null},
new Component[]{expendSortPane, sortAfterExpand},
};
double[] rowSize = {p, p, p, p, p};
double[] columnSize = {p, f};
@ -169,9 +167,8 @@ public class CellExpandAttrPane extends AbstractCellAttrPane {
}
}
sortAfterExpand.populate(cellExpandAttr);
extraPane.populate(cellElement);
cellExpandSortPane.populateBean(cellElement);
}
@ -217,11 +214,8 @@ public class CellExpandAttrPane extends AbstractCellAttrPane {
}
}
if (ComparatorUtils.equals(getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_ExpandD_Sort_After_Expand"))) {
sortAfterExpand.update(cellExpandAttr);
}
extraPane.update(cellElement);
cellExpandSortPane.updateBean(cellElement);
}
/**

40
designer-realize/src/main/java/com/fr/design/sort/celldscolumn/CellDSColumnSortGroupPane.java

@ -0,0 +1,40 @@
package com.fr.design.sort.celldscolumn;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.tabledata.wrapper.TableDataWrapper;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.sort.common.AbstractSortGroupPane;
import com.fr.design.sort.common.AbstractSortItemPane;
import com.fr.report.cell.cellattr.core.group.DSColumn;
import com.fr.report.core.sort.sortexpression.SortExpression;
public class CellDSColumnSortGroupPane extends AbstractSortGroupPane {
DSColumn dsColumn;
public CellDSColumnSortGroupPane(int sortGroupPaneWidth, int sortGroupPaneRightWidth) {
super(sortGroupPaneWidth, sortGroupPaneRightWidth);
}
public void populateDsColumn(DSColumn dsColumn) {
this.dsColumn = dsColumn;
}
@Override
protected AbstractSortItemPane refreshSortItemPane(int sortItemPaneWidth, int sortItemPaneRightWidth, SortExpression sortExpression) {
CellDSColumnSortItemPane cellDSColumnSortItemPane = new CellDSColumnSortItemPane(sortItemPaneWidth, sortItemPaneRightWidth);
java.util.Map<String, TableDataWrapper> tableDataWrapperMap =
DesignTableDataManager.getAllEditingDataSet(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getTarget());
TableDataWrapper tableDataWrapper = tableDataWrapperMap.get(dsColumn.getDSName());
if (tableDataWrapper != null) {
java.util.List<String> columnNameList = tableDataWrapper.calculateColumnNameList();
String[] columnNames = new String[columnNameList.size()];
columnNameList.toArray(columnNames);
cellDSColumnSortItemPane.sortAreaUiComboBox.removeAllItems();
for (String columnName : columnNames) {
cellDSColumnSortItemPane.sortAreaUiComboBox.addItem(columnName);
}
}
cellDSColumnSortItemPane.populateBean(sortExpression);
return cellDSColumnSortItemPane;
}
}

40
designer-realize/src/main/java/com/fr/design/sort/celldscolumn/CellDSColumnSortItemPane.java

@ -0,0 +1,40 @@
package com.fr.design.sort.celldscolumn;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.sort.common.AbstractSortItemPane;
import com.fr.design.sort.common.AbstractSortPane;
import com.fr.report.core.sort.sortexpression.SortExpression;
import javax.swing.*;
import java.awt.*;
public class CellDSColumnSortItemPane extends AbstractSortItemPane {
UIComboBox sortAreaUiComboBox;
public CellDSColumnSortItemPane(int sortItemPaneWidth, int sortItemPaneRightWidth) {
super(sortItemPaneWidth, sortItemPaneRightWidth);
}
@Override
public void initMainSortAreaPane(JPanel sortAreaPane) {
sortAreaUiComboBox = new UIComboBox(new String[0]);
sortAreaUiComboBox.setPreferredSize(new Dimension(sortItemPaneRightWidth, AbstractSortPane.PANE_COMPONENT_HEIGHT));
sortAreaPane.add(sortAreaUiComboBox);
}
public void populateBean(SortExpression sortExpression) {
sortAreaUiComboBox.setSelectedItem(sortExpression.getSortArea());
super.populateBean(sortExpression);
}
public SortExpression updateBean() {
SortExpression sortExpression = super.updateBean();
if (sortExpression != null && sortAreaUiComboBox.getSelectedItem() != null) {
sortExpression.setSortArea(sortAreaUiComboBox.getSelectedItem().toString());
}
return sortExpression;
}
}

62
designer-realize/src/main/java/com/fr/design/sort/celldscolumn/CellDSColumnSortPane.java

@ -0,0 +1,62 @@
package com.fr.design.sort.celldscolumn;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.sort.common.AbstractSortPane;
import com.fr.general.data.TableDataColumn;
import com.fr.report.cell.TemplateCellElement;
import com.fr.report.cell.cellattr.core.group.DSColumn;
import com.fr.report.core.sort.common.CellSortAttr;
import javax.swing.*;
public class CellDSColumnSortPane extends AbstractSortPane {
public CellDSColumnSortPane() {
super(220, 150);
//this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
}
@Override
protected void initSortGroupPane() {
sortGroupPane = new CellDSColumnSortGroupPane(sortPaneWidth, sortPaneRightWidth);
this.add(sortGroupPane);
}
@Override
protected CellSortAttr getCellSortAttr(TemplateCellElement cellElement) {
if (cellElement.getValue() instanceof DSColumn) {
DSColumn dsColumn = ((DSColumn) cellElement.getValue());
if (dsColumn.getCellSortAttr() == null) {
dsColumn.setCellSortAttr(new CellSortAttr());
}
return dsColumn.getCellSortAttr();
}
return null;
}
protected void populateSortArea(TemplateCellElement cellElement) {
super.populateSortArea(cellElement);
if (cellElement.getValue() instanceof DSColumn) {
DSColumn dsColumn = ((DSColumn) cellElement.getValue());
TableDataColumn tableDataColumn = dsColumn.getColumn();
if (tableDataColumn instanceof TableDataColumn) {
selfSortArea = TableDataColumn.getColumnName(tableDataColumn);
}
}
}
public void populateBean(TemplateCellElement cellElement) {
if (cellElement.getValue() instanceof DSColumn) {
DSColumn dsColumn = ((DSColumn) cellElement.getValue());
if (sortGroupPane != null) {
((CellDSColumnSortGroupPane) sortGroupPane).populateDsColumn(dsColumn);
}
}
super.populateBean(cellElement);
}
protected boolean needSortHeaderPane() {
return false;
}
}

19
designer-realize/src/main/java/com/fr/design/sort/cellexpand/CellExpandSortGroupPane.java

@ -0,0 +1,19 @@
package com.fr.design.sort.cellexpand;
import com.fr.design.sort.common.AbstractSortGroupPane;
import com.fr.design.sort.common.AbstractSortItemPane;
import com.fr.report.core.sort.sortexpression.SortExpression;
public class CellExpandSortGroupPane extends AbstractSortGroupPane {
public CellExpandSortGroupPane(int sortGroupPaneWidth, int sortGroupPaneRightWidth) {
super(sortGroupPaneWidth, sortGroupPaneRightWidth);
}
@Override
protected AbstractSortItemPane refreshSortItemPane(int sortItemPaneWidth, int sortItemPaneRightWidth, SortExpression sortExpression) {
AbstractSortItemPane abstractSortItemPane = new CellExpandSortItemPane( sortItemPaneWidth, sortItemPaneRightWidth);
abstractSortItemPane.populateBean(sortExpression);
return abstractSortItemPane;
}
}

37
designer-realize/src/main/java/com/fr/design/sort/cellexpand/CellExpandSortItemPane.java

@ -0,0 +1,37 @@
package com.fr.design.sort.cellexpand;
import com.fr.design.sort.common.AbstractSortPane;
import com.fr.design.sort.common.SortColumnRowPane;
import com.fr.design.sort.common.AbstractSortItemPane;
import com.fr.report.core.sort.sortexpression.SortExpression;
import com.fr.stable.ColumnRow;
import javax.swing.*;
public class CellExpandSortItemPane extends AbstractSortItemPane {
SortColumnRowPane columnRowPane;
public CellExpandSortItemPane(int sortItemPaneWidth, int sortItemPaneRightWidth) {
super(sortItemPaneWidth, sortItemPaneRightWidth);
}
@Override
public void initMainSortAreaPane(JPanel sortAreaPane) {
columnRowPane = new SortColumnRowPane(sortItemPaneRightWidth + 4, AbstractSortPane.PANE_COMPONENT_HEIGHT);
sortAreaPane.add(columnRowPane);
}
public void populateBean(SortExpression sortExpression) {
columnRowPane.populateBean(ColumnRow.valueOf(sortExpression.getSortArea()));
super.populateBean(sortExpression);
}
public SortExpression updateBean() {
SortExpression sortExpression = super.updateBean();
if (sortExpression != null) {
ColumnRow columnRow = columnRowPane.updateBean();
sortExpression.setSortArea(columnRow == null ? null : columnRow.toString());
}
return sortExpression;
}
}

39
designer-realize/src/main/java/com/fr/design/sort/cellexpand/CellExpandSortPane.java

@ -0,0 +1,39 @@
package com.fr.design.sort.cellexpand;
import com.fr.design.mainframe.cell.settingpane.CellExpandAttrPane;
import com.fr.design.sort.common.AbstractSortPane;
import com.fr.report.cell.TemplateCellElement;
import com.fr.report.cell.cellattr.CellExpandAttr;
import com.fr.report.core.sort.common.CellSortAttr;
import javax.swing.*;
public class CellExpandSortPane extends AbstractSortPane {
CellExpandAttrPane cellExpandAttrPane;
public CellExpandSortPane(CellExpandAttrPane cellExpandAttrPane) {
super(227, 155);
this.cellExpandAttrPane = cellExpandAttrPane;
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
}
@Override
protected void initSortGroupPane() {
sortGroupPane = new CellExpandSortGroupPane(sortPaneWidth, sortPaneRightWidth);
this.add(sortGroupPane);
}
@Override
protected CellSortAttr getCellSortAttr(TemplateCellElement cellElement) {
CellExpandAttr cellExpandAttr = cellElement.getCellExpandAttr();
if (cellExpandAttr != null) {
if (cellExpandAttr.getCellSortAttr() == null) {
cellExpandAttr.setCellSortAttr(new CellSortAttr());
}
return cellExpandAttr.getCellSortAttr();
}
return null;
}
}

152
designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortGroupPane.java

@ -0,0 +1,152 @@
package com.fr.design.sort.common;
import com.fr.base.svg.IconUtils;
import com.fr.design.event.ComponentChangeListener;
import com.fr.design.event.ComponentChangeObserver;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.i18n.Toolkit;
import com.fr.report.core.sort.sortexpression.CellSortExpression;
import com.fr.report.core.sort.sortexpression.SortExpression;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractSortGroupPane extends JPanel implements ComponentChangeObserver {
private static final int SECOND_SORT_LENGTH_REDUCTION = 13;
protected int sortGroupPaneWidth;
protected int sortGroupPaneRightWidth;
List<SortExpression> sortExpressions;
List<SortUIExpandablePane> sortUIExpandablePanes = new ArrayList<>();
AddSortItemBar addSortItemBar;
JPanel sortItemListPane;
UIButton uiButton;
String selfSortArea;
ComponentChangeListener componentChangeListener;
public AbstractSortGroupPane(int sortGroupPaneWidth, int sortGroupPaneRightWidth) {
this.sortGroupPaneRightWidth = sortGroupPaneRightWidth;
this.sortGroupPaneWidth = sortGroupPaneWidth;
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
initComponents();
}
private void initComponents() {
addSortItemBar = new AddSortItemBar(this);
sortItemListPane = new JPanel();
sortItemListPane.setLayout(new BoxLayout(sortItemListPane, BoxLayout.Y_AXIS));
this.add(sortItemListPane);
this.add(addSortItemBar);
}
public void populateBean(List<SortExpression> sortExpressions, String selfSortArea) {
this.sortItemListPane.removeAll();
this.selfSortArea = selfSortArea;
this.sortExpressions = sortExpressions;
this.sortUIExpandablePanes = new ArrayList<>();
for (int i = 0; i < sortExpressions.size(); i++) {
addSortItem(sortExpressions.get(i));
}
refresh();
}
protected abstract AbstractSortItemPane refreshSortItemPane(int sortItemPaneWidth, int sortItemPaneRightWidth, SortExpression sortExpression);
public List<SortExpression> updateBean() {
List<SortExpression> sortExpressions = new ArrayList<>();
for (SortUIExpandablePane sortUIExpandablePane : sortUIExpandablePanes) {
SortExpression sortExpression = null;
if (sortUIExpandablePane != null) {
AbstractSortItemPane abstractSortItemPane
= (AbstractSortItemPane) sortUIExpandablePane.getContentPane();
if (abstractSortItemPane != null) {
sortExpression = abstractSortItemPane.updateBean();
}
}
if (sortExpression != null) {
sortExpressions.add(sortExpression);
}
}
return sortExpressions;
}
public void removeSortItem(int no) {
if (no < sortExpressions.size()) {
sortItemListPane.remove(sortUIExpandablePanes.get(no));
sortExpressions.remove(no);
sortUIExpandablePanes.remove(no);
refresh();
}
}
public void removeSortItem(SortUIExpandablePane sortUIExpandablePane) {
for (int i = 0; i < sortUIExpandablePanes.size(); i++) {
if (sortUIExpandablePanes.get(i) == sortUIExpandablePane) {
removeSortItem(i);
return;
}
}
}
public void registerChangeListener(ComponentChangeListener componentChangeListener) {
this.componentChangeListener = componentChangeListener;
}
public void addSortItem(SortExpression sortExpression) {
int sortItemPaneWidth = sortGroupPaneWidth - SECOND_SORT_LENGTH_REDUCTION;
int sortItemPaneRightWidth = sortGroupPaneRightWidth - SECOND_SORT_LENGTH_REDUCTION;
if (sortExpression == null) {
sortExpression = new CellSortExpression(selfSortArea);
sortExpressions.add(sortExpression);
}
AbstractSortItemPane abstractSortItemPane =
refreshSortItemPane(sortItemPaneWidth, sortItemPaneRightWidth, sortExpression);
SortUIExpandablePane sortUIExpandablePane = new SortUIExpandablePane(abstractSortItemPane, this);
sortItemListPane.add(sortUIExpandablePane);
sortUIExpandablePanes.add(sortUIExpandablePane);
if (componentChangeListener != null) {
componentChangeListener.initListener(sortUIExpandablePane);
}
refresh();
}
protected void refresh() {
validate();
repaint();
revalidate();
}
class AddSortItemBar extends JPanel {
AbstractSortGroupPane sortGroupPane;
AddSortItemBar(AbstractSortGroupPane sortGroupPane) {
init();
this.sortGroupPane = sortGroupPane;
this.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 5));
}
void init() {
uiButton = new UIButton(Toolkit.i18nText("Fine-Design_Sort_Add_Second_Sort"),
IconUtils.readIcon("/com/fr/design/images/sort/add.png"));
uiButton.setPreferredSize(new Dimension(sortGroupPaneWidth - 4, AbstractSortPane.PANE_COMPONENT_HEIGHT));
this.add(uiButton);
uiButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sortGroupPane.addSortItem(null);
}
});
}
}
}

153
designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortItemPane.java

@ -0,0 +1,153 @@
package com.fr.design.sort.common;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.sort.expressionpane.CellSortExpressionPane;
import com.fr.design.sort.expressionpane.CustomSequenceSortExpressionPane;
import com.fr.design.sort.expressionpane.FormulaSortExpressionPane;
import com.fr.design.sort.expressionpane.SortExpressionPane;
import com.fr.report.core.sort.sortexpression.SortExpression;
import com.fr.report.core.sort.common.SortRule;
import com.fr.stable.StringUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractSortItemPane extends JPanel {
protected int sortItemPaneWidth;
protected int sortItemPaneRightWidth;
List<SortExpressionPane> sortExpressionPanes = new ArrayList<>();
SortExpressionPane currentSortExpressionPane = null;
JPanel sortBasisPanel = null;
UIComboBox sortRuleUiComboBox;
UIComboBox sortBasisUiComboBox;
JPanel sortAreaPane;
JPanel sortRulePane;
public AbstractSortItemPane(int sortItemPaneWidth, int sortItemPaneRightWidth) {
this.sortItemPaneWidth = sortItemPaneWidth;
this.sortItemPaneRightWidth = sortItemPaneRightWidth;
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
registerSortExpressionPanes();
initComponents();
}
private void initComponents() {
initSortAreaPane();
initSortBasisPanel();
initSortRulePane();
}
private void registerSortExpressionPanes() {
sortExpressionPanes.add(new CellSortExpressionPane(sortItemPaneRightWidth));
sortExpressionPanes.add(new FormulaSortExpressionPane(sortItemPaneRightWidth));
sortExpressionPanes.add(new CustomSequenceSortExpressionPane(sortItemPaneWidth, sortItemPaneRightWidth));
}
void initSortAreaPane() {
sortAreaPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, AbstractSortPane.PANE_COMPONENT_V_GAP));
sortAreaPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Sort_Sort_Area"), SwingConstants.LEFT));
sortAreaPane.add(AbstractSortPane.createIntervalUILabel());
initMainSortAreaPane(sortAreaPane);
this.add(sortAreaPane);
}
public abstract void initMainSortAreaPane(JPanel sortAreaPane);
void initSortRulePane() {
sortRulePane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, AbstractSortPane.PANE_COMPONENT_V_GAP));
sortRuleUiComboBox = new UIComboBox(new String[]{SortRule.ASC.getDescription(),
SortRule.DES.getDescription(), SortRule.NO_SORT.getDescription()});
sortRuleUiComboBox.setPreferredSize(new Dimension(sortItemPaneRightWidth, AbstractSortPane.PANE_COMPONENT_HEIGHT));
sortRulePane.add(new UILabel(Toolkit.i18nText("Fine-Design_Sort_Sort_Rule"), SwingConstants.LEFT));
sortRulePane.add(AbstractSortPane.createIntervalUILabel());
sortRulePane.add(sortRuleUiComboBox);
this.add(sortRulePane);
}
void initSortBasisPanel() {
sortBasisPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, AbstractSortPane.PANE_COMPONENT_V_GAP));
sortBasisUiComboBox = new UIComboBox(getSortNames());
sortBasisUiComboBox.setPreferredSize(new Dimension(sortItemPaneRightWidth, AbstractSortPane.PANE_COMPONENT_HEIGHT));
sortBasisUiComboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (sortExpressionPanes.get(sortBasisUiComboBox.getSelectedIndex()) != currentSortExpressionPane) {
if (currentSortExpressionPane != null) {
currentSortExpressionPane.setVisible(false);
}
currentSortExpressionPane = sortExpressionPanes.get(sortBasisUiComboBox.getSelectedIndex());
refreshCurrentSortExpressionPane();
}
}
});
sortBasisPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Sort_Sort_Basis"), SwingConstants.LEFT));
sortBasisPanel.add(AbstractSortPane.createIntervalUILabel());
sortBasisPanel.add(sortBasisUiComboBox);
this.add(sortBasisPanel);
for (SortExpressionPane sortExpressionPane : sortExpressionPanes) {
this.add(sortExpressionPane);
sortExpressionPane.setVisible(false);
}
}
private void refreshCurrentSortExpressionPane() {
currentSortExpressionPane.setVisible(true);
sortAreaPane.setVisible(currentSortExpressionPane.needSortArea());
sortRulePane.setVisible(currentSortExpressionPane.needSortRule());
}
private String[] getSortNames() {
String[] sortNames = new String[sortExpressionPanes.size()];
for (int i = 0; i < sortExpressionPanes.size(); i++) {
sortNames[i] = sortExpressionPanes.get(i).getSortName();
}
return sortNames;
}
public void populateBean(SortExpression sortExpression) {
if (sortExpression.getSortRule() == SortRule.ASC) {
sortRuleUiComboBox.setSelectedIndex(0);
} else if (sortExpression.getSortRule() == SortRule.DES) {
sortRuleUiComboBox.setSelectedIndex(1);
} else if (sortExpression.getSortRule() == SortRule.NO_SORT) {
sortRuleUiComboBox.setSelectedIndex(2);
}
for (int i = 0; i < sortExpressionPanes.size(); i++) {
if (StringUtils.equals(sortExpression.getSortName(), sortExpressionPanes.get(i).getSortName())) {
if (currentSortExpressionPane != null) {
currentSortExpressionPane.setVisible(false);
}
currentSortExpressionPane = sortExpressionPanes.get(i);
currentSortExpressionPane.populateBean(sortExpression);
sortBasisUiComboBox.setSelectedIndex(i);
refreshCurrentSortExpressionPane();
break;
}
}
refresh();
}
public SortExpression updateBean() {
SortExpression sortExpression = currentSortExpressionPane.updateBean();
if (sortExpression != null) {
String sortRule = sortRuleUiComboBox.getSelectedItem().toString();
if (StringUtils.isNotBlank(sortRule)) {
sortExpression.setSortRule(SortRule.parse(sortRule));
}
}
return sortExpression;
}
protected void refresh() {
validate();
repaint();
revalidate();
}
}

112
designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortPane.java

@ -0,0 +1,112 @@
package com.fr.design.sort.common;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.sort.header.SortHeaderPane;
import com.fr.report.cell.TemplateCellElement;
import com.fr.report.core.sort.common.CellSortAttr;
import com.fr.report.core.sort.sortexpression.CellSortExpression;
import com.fr.report.core.sort.sortexpression.SortExpression;
import com.fr.report.core.sort.header.SortHeader;
import com.fr.stable.ColumnRow;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractSortPane extends JPanel {
protected int sortPaneWidth;
protected int sortPaneRightWidth;
public static final int PANE_COMPONENT_HEIGHT = 20;
public static final int PANE_COMPONENT_V_GAP = 4;
public static final int PANE_COMPONENT_H_GAP = 14;
protected AbstractSortGroupPane sortGroupPane;
protected SortHeaderPane sortHeaderPane;
protected String selfSortArea;
protected String defaultHeaderArea;
public AbstractSortPane(int sortPaneWidth, int sortPaneRightWidth) {
this.sortPaneWidth = sortPaneWidth;
this.sortPaneRightWidth = sortPaneRightWidth;
initComponents();
}
private void initComponents() {
initSortGroupPane();
if (needSortHeaderPane()) {
sortHeaderPane = new SortHeaderPane(sortPaneWidth, sortPaneRightWidth + 5);
this.add(sortHeaderPane);
}
}
protected abstract void initSortGroupPane();
protected boolean needSortHeaderPane() {
return true;
}
protected abstract CellSortAttr getCellSortAttr(TemplateCellElement cellElement);
public void populateBean(TemplateCellElement cellElement) {
populateSortArea(cellElement);
List<SortExpression> sortExpressions = null;
CellSortAttr cellSortAttr = getCellSortAttr(cellElement);
if (cellSortAttr != null) {
sortExpressions = cellSortAttr.getSortExpressions();
}
if (sortExpressions == null) {
sortExpressions = new ArrayList<>();
}
sortGroupPane.populateBean(sortExpressions, selfSortArea);
if (needSortHeaderPane()) {
SortHeader sortHeader = null;
if (cellSortAttr != null) {
sortHeader = cellSortAttr.getSortHeader();
}
sortHeaderPane.populateBean(sortHeader, defaultHeaderArea);
}
refresh();
}
protected void populateSortArea(TemplateCellElement cellElement) {
int row = cellElement.getRow();
int column = cellElement.getColumn();
selfSortArea = ColumnRow.valueOf(column, row).toString();
if (row > 0) {
defaultHeaderArea = ColumnRow.valueOf(column, row - 1).toString();
} else {
defaultHeaderArea = null;
}
}
public void updateBean(TemplateCellElement cellElement) {
List<SortExpression> sortExpressions = sortGroupPane.updateBean();
CellSortAttr cellSortAttr = getCellSortAttr(cellElement);
cellSortAttr.setSortExpressions(sortExpressions);
if (needSortHeaderPane()) {
SortHeader sortHeader = sortHeaderPane.updateBean(cellElement);
if (sortHeader != null) {
sortHeader.setSortArea(selfSortArea);
}
cellSortAttr.setSortHeader(sortHeader);
}
}
protected void refresh() {
validate();
repaint();
revalidate();
}
public static UILabel createIntervalUILabel() {
return createIntervalUILabel(PANE_COMPONENT_H_GAP);
}
public static UILabel createIntervalUILabel(int vGap) {
UILabel uiLabel = new UILabel();
uiLabel.setPreferredSize(new Dimension(vGap, 10));
return uiLabel;
}
}

277
designer-realize/src/main/java/com/fr/design/sort/common/SortColumnRowPane.java

@ -0,0 +1,277 @@
package com.fr.design.sort.common;
import com.fr.base.Style;
import com.fr.base.background.ColorBackground;
import com.fr.base.svg.IconUtils;
import com.fr.design.designer.TargetComponent;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.ElementCasePane;
import com.fr.design.selection.SelectionEvent;
import com.fr.design.selection.SelectionListener;
import com.fr.design.sort.header.HeaderAreaPane;
import com.fr.grid.selection.CellSelection;
import com.fr.grid.selection.Selection;
import com.fr.log.FineLoggerFactory;
import com.fr.report.cell.DefaultTemplateCellElement;
import com.fr.report.cell.TemplateCellElement;
import com.fr.report.cell.cellattr.CellExpandAttr;
import com.fr.report.cell.cellattr.core.group.DSColumn;
import com.fr.report.core.sort.common.CellSortable;
import com.fr.report.core.sort.header.SortHeader;
import com.fr.report.elementcase.TemplateElementCase;
import com.fr.stable.ColumnRow;
import com.fr.stable.EssentialUtils;
import com.fr.stable.StringUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class SortColumnRowPane extends JPanel implements UIObserver {
int paneWidth;
int paneHeight;
int jTextFieldWidth;
JTextField colJTextField;
JTextField rowJTextField;
UIButton selectButton;
private boolean isAlreadyAddListener = false;
private CellSelection oldSelection;
private SelectionListener gridSelectionChangeListener;
UIObserverListener uiObserverListener;
private final static Icon DISABLED_ICON = IconUtils.readIcon("/com/fr/design/images/buttonicon/select_disabled.svg");
private final static Icon ENABLE_ICON = IconUtils.readIcon("/com/fr/design/images/buttonicon/select_normal.svg");
private boolean enabled;
HeaderAreaPane.CellSelectionManager cellSelectionManager;
public SortColumnRowPane(int paneWidth, int paneHeight) {
this.paneWidth = paneWidth;
this.paneHeight = paneHeight;
initComponents();
}
private void initComponents() {
initSize();
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
intUILabel();
initTextField();
initSelectButton();
this.setSize(new Dimension(paneWidth, paneHeight));
}
void initSize() {
jTextFieldWidth = (paneWidth - 40) / 2;
}
void intUILabel() {
UILabel uiLabel = new UILabel(IconUtils.readIcon("/com/fr/design/images/buttonicon/propertiestab/cellelement_normal.png"));
this.add(uiLabel);
}
public static boolean isAvailableColumnRow(ColumnRow columnRow) {
return columnRow != null && columnRow.getRow() != -1 && columnRow.getColumn() != -1;
}
void initTextField() {
colJTextField = new JTextField();
colJTextField.setEditable(false);
rowJTextField = new JTextField();
rowJTextField.setEditable(false);
colJTextField.setPreferredSize(new Dimension(jTextFieldWidth, paneHeight));
rowJTextField.setPreferredSize(new Dimension(jTextFieldWidth, paneHeight));
this.add(colJTextField);
this.add(rowJTextField);
}
void initSelectButton() {
selectButton = new UIButton(ENABLE_ICON);
selectButton.addMouseListener(new SelectActionListener(this));
this.add(selectButton);
}
public void populateBean(ColumnRow columnRow, boolean enabled, HeaderAreaPane.CellSelectionManager cellSelectionManager) {
this.cellSelectionManager = cellSelectionManager;
populateBean(columnRow, enabled);
}
public void populateBean(ColumnRow columnRow) {
populateBean(columnRow, true);
}
public void populateBean(ColumnRow columnRow, boolean enabled) {
this.enabled = enabled;
if (SortColumnRowPane.isAvailableColumnRow(columnRow)) {
colJTextField.setText(EssentialUtils.convertIntToABC(columnRow.column + 1));
rowJTextField.setText(String.valueOf(columnRow.row + 1));
} else {
colJTextField.setText(StringUtils.EMPTY);
rowJTextField.setText(StringUtils.EMPTY);
}
if (enabled) {
selectButton.setIcon(ENABLE_ICON);
} else {
selectButton.setIcon(DISABLED_ICON);
}
selectButton.setEnabled(false);
refresh();
}
public void setColumnRow(ColumnRow columnRow) {
populateBean(columnRow);
uiObserverListener.doChange();
}
public ColumnRow updateBean() {
if (StringUtils.isNotBlank(colJTextField.getText()) && StringUtils.isNotBlank(rowJTextField.getText())) {
return ColumnRow.valueOf(colJTextField.getText() + rowJTextField.getText());
}
return ColumnRow.ERROR;
}
@Override
public void registerChangeListener(UIObserverListener listener) {
this.uiObserverListener = listener;
}
@Override
public boolean shouldResponseChangeListener() {
return true;
}
class SelectActionListener extends MouseAdapter {
SortColumnRowPane columnRowPane;
ColumnRow oldColumnRow;
Map<ColumnRow, Style> disableHeaderCellsStyleMap = new HashMap<>();
java.util.List<TemplateCellElement> tempHeaderCells = new ArrayList<>();
SelectActionListener(SortColumnRowPane columnRowPane) {
this.columnRowPane = columnRowPane;
}
@Override
public void mouseClicked(MouseEvent e) {
if (enabled) {
ElementCasePane elementCasePane = getCurrentElementCase();
if (elementCasePane == null || isAlreadyAddListener) {
return;
}
oldColumnRow = columnRowPane.updateBean();
prepareSelectHeader(elementCasePane);
gridSelectionChangeListener = new SelectionListener() {
@Override
public void selectionChanged(SelectionEvent e) {
completeSelectHeader(elementCasePane);
}
};
elementCasePane.addSelectionChangeListener(gridSelectionChangeListener);
isAlreadyAddListener = true;
}
}
private void prepareSelectHeader(ElementCasePane elementCasePane) {
ashDisableHeaderCellsStyle(elementCasePane.getEditingElementCase());
oldSelection = (CellSelection) elementCasePane.getSelection();
elementCasePane.getGrid().setNotShowingTableSelectPane(false);
elementCasePane.setRepeatSelection(true);
elementCasePane.setEditable(false);
elementCasePane.repaint(10);
}
private void completeSelectHeader(ElementCasePane elementCasePane) {
Selection selection = elementCasePane.getSelection();
if (selection instanceof CellSelection) {
CellSelection cellselection = (CellSelection) selection;
ColumnRow columnRow = ColumnRow.valueOf(cellselection.getColumn(), cellselection.getRow());
elementCasePane.setOldSelecton(oldSelection);
oldSelection.getQuickEditor(elementCasePane);
if (cellSelectionManager == null || !cellSelectionManager.isNotSelectables(columnRow)) {
if (cellSelectionManager != null) {
cellSelectionManager.removeNotSelectables(oldColumnRow);
cellSelectionManager.addNotSelectables(columnRow);
}
columnRowPane.setColumnRow(columnRow);
}
restoreDisableHeaderCellsStyle(elementCasePane.getEditingElementCase());
}
elementCasePane.removeSelectionChangeListener(gridSelectionChangeListener);
isAlreadyAddListener = false;
elementCasePane.getGrid().setNotShowingTableSelectPane(true);
elementCasePane.setRepeatSelection(false);
elementCasePane.setEditable(true);
elementCasePane.repaint();
oldColumnRow = null;
}
private void ashDisableHeaderCellsStyle(TemplateElementCase elementCase) {
if (cellSelectionManager != null) {
java.util.List<ColumnRow> notSelectables = cellSelectionManager.getNotSelectables();
disableHeaderCellsStyleMap = new HashMap<>();
tempHeaderCells = new ArrayList<>();
for (ColumnRow columnRow : notSelectables) {
TemplateCellElement templateCellElement
= elementCase.getTemplateCellElement(columnRow.column, columnRow.row);
if (templateCellElement == null) {
templateCellElement = new DefaultTemplateCellElement(columnRow.column, columnRow.row);
elementCase.addCellElement(templateCellElement);
tempHeaderCells.add(templateCellElement);
}
Style style = templateCellElement.getStyle();
disableHeaderCellsStyleMap.put(columnRow, style);
style = style.deriveBackground(ColorBackground.getInstance(Color.gray));
templateCellElement.setStyle(style);
}
}
}
private void restoreDisableHeaderCellsStyle(TemplateElementCase elementCase) {
if (cellSelectionManager != null) {
try {
for (ColumnRow headerColumnRow : disableHeaderCellsStyleMap.keySet()) {
TemplateCellElement headerTemplateCellElement
= elementCase.getTemplateCellElement(headerColumnRow.column, headerColumnRow.row);
headerTemplateCellElement.setStyle(disableHeaderCellsStyleMap.get(headerColumnRow));
}
for (TemplateCellElement templateCellElement : tempHeaderCells) {
elementCase.removeCellElement(templateCellElement);
}
disableHeaderCellsStyleMap = new HashMap<>();
tempHeaderCells = new ArrayList<>();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
}
}
}
protected void refresh() {
validate();
repaint();
revalidate();
}
public static ElementCasePane getCurrentElementCase() {
try {
TargetComponent targetComponent
= HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getCurrentElementCasePane();
if (targetComponent instanceof ElementCasePane) {
return (ElementCasePane) targetComponent;
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
return null;
}
}

119
designer-realize/src/main/java/com/fr/design/sort/common/SortUIExpandablePane.java

@ -0,0 +1,119 @@
package com.fr.design.sort.common;
import com.fr.base.BaseUtils;
import com.fr.base.svg.IconUtils;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class SortUIExpandablePane extends JPanel {
private static final long serialVersionUID = 1L;
private HeaderPane headerPane;
private AbstractSortItemPane contentPane;
private AbstractSortGroupPane sortGroupPane;
private JPanel wrapPane;
private SortUIExpandablePane self = this;
public JPanel getContentPane() {
return contentPane;
}
public SortUIExpandablePane(AbstractSortItemPane contentPane, AbstractSortGroupPane sortGroupPane) {
super();
this.sortGroupPane = sortGroupPane;
this.contentPane = contentPane;
initComponents();
wrapPane.setBorder(BorderFactory.createLineBorder(new Color(217, 218, 221), 1));
wrapPane.setBackground(Color.WHITE);
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 5));
}
private void initComponents() {
wrapPane = new JPanel();
wrapPane.setLayout(new BorderLayout());
headerPane = new HeaderPane(sortGroupPane);
headerPane.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
setContentPanelShow(!contentPane.isVisible());
}
});
headerPane.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(217, 218, 221)));
contentPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
wrapPane.add(headerPane, BorderLayout.NORTH);
wrapPane.add(contentPane, BorderLayout.CENTER);
setContentPanelShow(true);
this.add(wrapPane);
}
private void setContentPanelShow(Boolean show) {
contentPane.setVisible(show);
headerPane.setShow(show);
}
class HeaderPane extends JPanel implements UIObserver {
UILabel iconUiLabel;
UILabel closeButton;
AbstractSortGroupPane sortGroupPane;
UIObserverListener uiObserverListener;
HeaderPane(AbstractSortGroupPane sortGroupPane) {
this.sortGroupPane = sortGroupPane;
this.setLayout(new FlowLayout(FlowLayout.LEFT, 3, 0));
initComponents();
}
private void initComponents() {
iconUiLabel = new UILabel();
this.add(iconUiLabel);
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Second_Sort"));
this.add(uiLabel);
this.add(AbstractSortPane.createIntervalUILabel(108));
closeButton = new UILabel(IconUtils.readIcon("/com/fr/design/images/control/close.png"));
closeButton.setPreferredSize(new Dimension(16, 20));
this.add(closeButton);
closeButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
sortGroupPane.removeSortItem(self);
if (uiObserverListener != null) {
uiObserverListener.doChange();
}
}
});
this.setPreferredSize(new Dimension(contentPane.sortItemPaneWidth + 7, AbstractSortPane.PANE_COMPONENT_HEIGHT));
}
public void setShow(boolean show) {
if (show) {
iconUiLabel.setIcon(IconUtils.readIcon("/com/fr/design/images/sort/down_arrow.png"));
} else {
iconUiLabel.setIcon(IconUtils.readIcon("/com/fr/design/images/sort/left_arrow.png"));
}
}
@Override
public void registerChangeListener(UIObserverListener uiObserverListener) {
this.uiObserverListener = uiObserverListener;
}
@Override
public boolean shouldResponseChangeListener() {
return true;
}
}
}

32
designer-realize/src/main/java/com/fr/design/sort/expressionpane/CellSortExpressionPane.java

@ -0,0 +1,32 @@
package com.fr.design.sort.expressionpane;
import com.fr.design.i18n.Toolkit;
import com.fr.locale.InterProviderFactory;
import com.fr.report.core.sort.sortexpression.CellSortExpression;
import java.awt.*;
public class CellSortExpressionPane extends SortExpressionPane<CellSortExpression> {
public CellSortExpressionPane(int with) {
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
}
@Override
public String getSortName() {
return InterProviderFactory.getProvider().getLocText("Fine-Engine_Sort_Cell");
}
@Override
public void populateBean(CellSortExpression cellSortExpression) {
}
@Override
public CellSortExpression updateBean() {
return new CellSortExpression();
}
}

190
designer-realize/src/main/java/com/fr/design/sort/expressionpane/CustomSequenceEditPane.java

@ -0,0 +1,190 @@
package com.fr.design.sort.expressionpane;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ilist.UIList;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.alphafine.listener.DocumentAdapter;
import com.fr.design.mainframe.dnd.SerializableTransferable;
import com.fr.design.mainframe.share.ui.base.PlaceholderTextArea;
import com.fr.locale.InterProviderFactory;
import com.fr.report.core.sort.sortexpression.CustomSequenceSortExpression;
import com.fr.stable.StringUtils;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceAdapter;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.util.ArrayList;
import java.util.List;
public class CustomSequenceEditPane extends BasicPane {
java.util.List<String> customSequence;
JSplitPane jSplitPane;
JPanel referenceSequencePanel;
JPanel editSequencePanel;
JTextArea jTextArea;
CustomSequenceEditPane(java.util.List<String> customSequence) {
this.customSequence = customSequence;
initComponents();
}
void initComponents() {
this.setLayout(new BorderLayout());
initReferenceSequencePanel();
initEditSequencePanel();
initSplitPane();
}
void initSplitPane() {
jSplitPane = new JSplitPane();
this.add(jSplitPane);
jSplitPane.setOneTouchExpandable(true);
jSplitPane.setContinuousLayout(true);
jSplitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
jSplitPane.setLeftComponent(referenceSequencePanel);
jSplitPane.setRightComponent(editSequencePanel);
jSplitPane.setDividerSize(10);
jSplitPane.setDividerLocation(200);
}
void initReferenceSequencePanel() {
referenceSequencePanel = new JPanel();
referenceSequencePanel.setLayout(new BoxLayout(referenceSequencePanel, BoxLayout.Y_AXIS));
JPanel titlePane = new JPanel(new FlowLayout(FlowLayout.LEFT));
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Reference_Sequence"));
titlePane.add(uiLabel);
referenceSequencePanel.add(titlePane);
UIScrollPane uiScrollPane = new UIScrollPane(getReferenceSequenceList());
uiScrollPane.setPreferredSize(new Dimension(200, 300));
referenceSequencePanel.add(uiScrollPane);
referenceSequencePanel.setSize(new Dimension(200, 400));
}
private UIList getReferenceSequenceList() {
UIList uiList = new UIList(getReferenceSequenceModel());
new CustomSequenceEditDragSource(uiList, DnDConstants.ACTION_MOVE);
return uiList;
}
private String[] getReferenceSequenceModel() {
List<List<String>> customSequences = CustomSequenceSortExpression.getReferenceCustomSequences();
String[] listModel = new String[customSequences.size()];
for (int i = 0; i < customSequences.size(); i++) {
listModel[i] = CustomSequenceSortExpression.customSequenceToString(customSequences.get(i), ",");
}
return listModel;
}
void initEditSequencePanel() {
editSequencePanel = new JPanel();
editSequencePanel.setLayout(new BoxLayout(editSequencePanel, BoxLayout.Y_AXIS));
JPanel titlePane = new JPanel(new FlowLayout(FlowLayout.LEFT));
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Input_Sequence"));
titlePane.add(uiLabel);
UILabel uiLabel2 = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Please_Interlace_Sequence_Elements"));
uiLabel2.setForeground(Color.lightGray);
titlePane.add(uiLabel2);
editSequencePanel.add(titlePane);
jTextArea = getTextArea();
UIScrollPane uiScrollPane = new UIScrollPane(jTextArea);
uiScrollPane.setPreferredSize(new Dimension(475, 300));
editSequencePanel.add(uiScrollPane);
editSequencePanel.setSize(new Dimension(475, 300));
}
JTextArea getTextArea() {
PlaceholderTextArea placeholderTextArea = new PlaceholderTextArea(10, 10, getPlaceholderText());
new CustomSequenceEditDropTarget(placeholderTextArea, CustomSequenceSortExpression.getReferenceCustomSequences());
placeholderTextArea.setText(CustomSequenceSortExpression.customSequenceToString(customSequence, "\n"));
placeholderTextArea.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent e) {
placeholderTextArea.repaint();
}
});
return placeholderTextArea;
}
String getPlaceholderText() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(Toolkit.i18nText("Fine-Design_Sort_Please_Interlace_Sequence_Elements_Such_As") + "\n");
stringBuilder.append(Toolkit.i18nText("Fine-Design_Sort_Department_One") + "\n");
stringBuilder.append(Toolkit.i18nText("Fine-Design_Sort_Department_Two") + "\n");
stringBuilder.append(Toolkit.i18nText("Fine-Design_Sort_Department_Three") + "\n");
return stringBuilder.toString();
}
@Override
protected String title4PopupWindow() {
return InterProviderFactory.getProvider().getLocText("Fine-Engine_Sort_Custom_Sequence");
}
class CustomSequenceEditDragSource extends DragSourceAdapter implements DragGestureListener {
private DragSource source;
public CustomSequenceEditDragSource(UIList uiList, int actions) {
source = new DragSource();
source.createDefaultDragGestureRecognizer(uiList, actions, this);
}
public void dragGestureRecognized(DragGestureEvent dge) {
Component comp = dge.getComponent();
if (comp instanceof UIList) {
UIList uiList = (UIList) comp;
source.startDrag(dge, DragSource.DefaultLinkDrop, new SerializableTransferable(uiList.getSelectedIndex()), this);
}
}
}
class CustomSequenceEditDropTarget extends DropTargetAdapter {
java.util.List<java.util.List<String>> customSequences = new ArrayList<>();
public CustomSequenceEditDropTarget(PlaceholderTextArea jPanel, java.util.List<java.util.List<String>> customSequences) {
new DropTarget(jPanel, this);
this.customSequences = customSequences;
}
@Override
public void drop(DropTargetDropEvent dtde) {
try {
Transferable transferable = dtde.getTransferable();
DataFlavor[] dataFlavors = transferable.getTransferDataFlavors();
if (dataFlavors.length == 1) {
Integer index = (Integer) transferable.getTransferData(dataFlavors[0]);
JTextArea jTextArea = (JTextArea) dtde.getDropTargetContext().getComponent();
String text = jTextArea.getText();
if (StringUtils.isNotEmpty(text) && !text.endsWith("\n")) {
text += "\n";
}
java.util.List<String> customSequence = customSequences.get(index);
for (int i = 0; i < customSequence.size(); i++) {
text += customSequence.get(i) + "\n";
}
jTextArea.setText(text);
}
} catch (Exception e) {
}
}
}
public List<String> updateBean() {
return CustomSequenceSortExpression.stringToCustomSequence(jTextArea.getText(), "\n");
}
}

66
designer-realize/src/main/java/com/fr/design/sort/expressionpane/CustomSequencePane.java

@ -0,0 +1,66 @@
package com.fr.design.sort.expressionpane;
import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.sort.common.AbstractSortPane;
import com.fr.report.core.sort.sortexpression.CustomSequenceSortExpression;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
public class CustomSequencePane extends JPanel {
protected UITextField textField;
protected UIButton button;
List<String> customSequence;
public CustomSequencePane(int width) {
this.setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0));
this.initComponents(width);
}
protected void initComponents(int width) {
textField = new UITextField();
textField.setEditable(false);
textField.setPreferredSize(new Dimension(width - 20, AbstractSortPane.PANE_COMPONENT_HEIGHT));
Icon icon = IconUtils.readIcon("/com/fr/design/images/sort/sequence.png");
button = new UIButton(icon);
button.setBackground(Color.RED);
button.setOpaque(false);
button.setCursor(new Cursor(Cursor.HAND_CURSOR));
button.setPreferredSize(new Dimension(20, AbstractSortPane.PANE_COMPONENT_HEIGHT));
MouseAdapter mouseAdapter = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
CustomSequenceEditPane customSequenceEditPane = new CustomSequenceEditPane(customSequence);
customSequenceEditPane.showWindowWithCustomSize(DesignerContext.getDesignerFrame(), new DialogActionAdapter() {
@Override
public void doOk() {
customSequence = customSequenceEditPane.updateBean();
textField.setText(CustomSequenceSortExpression.customSequenceToString(customSequence, ","));
}
}, new Dimension(700, 400)).setVisible(true);
}
};
button.addMouseListener(mouseAdapter);
textField.addMouseListener(mouseAdapter);
this.add(textField);
this.add(button);
}
public List<String> updateBean() {
return customSequence;
}
public void populateBean(List<String> customSequence) {
this.customSequence = customSequence;
textField.setText(CustomSequenceSortExpression.customSequenceToString(customSequence, ","));
}
}

37
designer-realize/src/main/java/com/fr/design/sort/expressionpane/CustomSequenceSortExpressionPane.java

@ -0,0 +1,37 @@
package com.fr.design.sort.expressionpane;
import com.fr.design.sort.common.AbstractSortPane;
import com.fr.locale.InterProviderFactory;
import com.fr.report.core.sort.sortexpression.CustomSequenceSortExpression;
import javax.swing.*;
import java.awt.*;
import java.util.List;
public class CustomSequenceSortExpressionPane extends SortExpressionPane<CustomSequenceSortExpression> {
CustomSequencePane customSequencePane;
public CustomSequenceSortExpressionPane(int width, int rightWidth) {
this.setLayout(new FlowLayout(FlowLayout.RIGHT, 2, 0));
customSequencePane = new CustomSequencePane(rightWidth + 5);
this.add(customSequencePane);
}
@Override
public String getSortName() {
return InterProviderFactory.getProvider().getLocText("Fine-Engine_Sort_Custom_Sequence");
}
@Override
public void populateBean(CustomSequenceSortExpression customSequenceSortExpression) {
List<String> customSequence = customSequenceSortExpression.getCustomSequence();
customSequencePane.populateBean(customSequence);
}
@Override
public CustomSequenceSortExpression updateBean() {
List<String> customSequence = customSequencePane.updateBean();
return new CustomSequenceSortExpression(customSequence);
}
}

42
designer-realize/src/main/java/com/fr/design/sort/expressionpane/FormulaSortExpressionPane.java

@ -0,0 +1,42 @@
package com.fr.design.sort.expressionpane;
import com.fr.design.formula.TinyFormulaPane;
import com.fr.design.sort.common.AbstractSortPane;
import com.fr.locale.InterProviderFactory;
import com.fr.report.core.sort.sortexpression.FormulaSortExpression;
import java.awt.*;
public class FormulaSortExpressionPane extends SortExpressionPane<FormulaSortExpression> {
TinyFormulaPane tinyFormulaPane;
public FormulaSortExpressionPane(int width) {
this.setLayout(new FlowLayout(FlowLayout.RIGHT, 2, 0));
tinyFormulaPane = new TinyFormulaPane();
tinyFormulaPane.setPreferredSize(new Dimension(width + 5, AbstractSortPane.PANE_COMPONENT_HEIGHT));
this.add(tinyFormulaPane);
}
@Override
public String getSortName() {
return InterProviderFactory.getProvider().getLocText("Fine-Engine_Sort_Formula");
}
@Override
public void populateBean(FormulaSortExpression formulaSortExpression) {
String formula = formulaSortExpression.getFormula();
tinyFormulaPane.getUITextField().setText(formula);
}
@Override
public FormulaSortExpression updateBean() {
String formula = tinyFormulaPane.getUITextField().getText();
return new FormulaSortExpression(formula);
}
public boolean needSortArea() {
return false;
}
}

23
designer-realize/src/main/java/com/fr/design/sort/expressionpane/SortExpressionPane.java

@ -0,0 +1,23 @@
package com.fr.design.sort.expressionpane;
import com.fr.report.core.sort.sortexpression.SortExpression;
import javax.swing.*;
public abstract class SortExpressionPane<T extends SortExpression> extends JPanel {
public abstract String getSortName();
public abstract void populateBean(T sortExpression);
public abstract T updateBean();
public boolean needSortArea() {
return true;
}
public boolean needSortRule() {
return true;
}
}

267
designer-realize/src/main/java/com/fr/design/sort/header/HeaderAreaPane.java

@ -0,0 +1,267 @@
package com.fr.design.sort.header;
import com.fr.design.designer.TargetComponent;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.ElementCasePane;
import com.fr.design.sort.common.AbstractSortPane;
import com.fr.design.sort.common.SortColumnRowPane;
import com.fr.log.FineLoggerFactory;
import com.fr.report.cell.TemplateCellElement;
import com.fr.report.cell.cellattr.CellExpandAttr;
import com.fr.report.cell.cellattr.core.group.DSColumn;
import com.fr.report.core.sort.common.CellSortable;
import com.fr.report.core.sort.header.SortHeader;
import com.fr.report.elementcase.TemplateElementCase;
import com.fr.stable.ColumnRow;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class HeaderAreaPane extends JPanel {
protected int headerAreaPaneWidth;
protected int headerAreaPaneRightWidth;
private CellSelectionManager cellSelectionManager = new CellSelectionManager();
AreaJLayeredPane areaJLayeredPane;
HeaderAreaPane(int headerAreaPaneWidth, int headerAreaPaneRightWidth) {
this.headerAreaPaneWidth = headerAreaPaneWidth;
this.headerAreaPaneRightWidth = headerAreaPaneRightWidth;
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
initComponents();
}
void initComponents() {
initUILabel();
initLayeredPane();
}
void initUILabel() {
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Header_Area"), SwingConstants.LEFT);
this.add(uiLabel);
this.add(AbstractSortPane.createIntervalUILabel());
}
void initLayeredPane() {
areaJLayeredPane = new AreaJLayeredPane();
this.add(areaJLayeredPane);
}
public void populateBean(ColumnRow columnRow, boolean showHeaderArea) {
boolean enabled = true;
ElementCasePane elementCasePane = getCurrentElementCase();
if (elementCasePane != null) {
enabled = elementCasePane.isSelectedOneCell();
}
areaJLayeredPane.populateBean(columnRow, showHeaderArea, enabled);
}
public ColumnRow updateBean(TemplateCellElement cellElement) {
ElementCasePane elementCasePane = getCurrentElementCase();
if (elementCasePane != null) {
if (!elementCasePane.isSelectedOneCell()) {
return getOldColumnRow(cellElement);
}
}
return areaJLayeredPane.updateBean();
}
private ColumnRow getOldColumnRow(TemplateCellElement cellElement) {
try {
SortHeader sortHeader
= cellElement.getCellExpandAttr().getCellSortAttr().getSortHeader();
String headerArea = sortHeader.getHeaderArea();
if (headerArea == null) {
return null;
} else {
return ColumnRow.valueOf(headerArea);
}
} catch (Exception ignore) {
return null;
}
}
private ElementCasePane getCurrentElementCase() {
try {
TargetComponent targetComponent
= HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getCurrentElementCasePane();
if (targetComponent instanceof ElementCasePane) {
return (ElementCasePane) targetComponent;
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
return null;
}
class AreaJLayeredPane extends JPanel {
SortColumnRowPane columnRowPane;
JLayeredPane jLayeredPane;
UIComboBox uiComboBox;
boolean populateBeaning;
AreaJLayeredPane() {
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
initComponents();
}
private void initComponents() {
initUIComboBox();
initJLayeredPane();
}
void initUIComboBox() {
uiComboBox = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_None"), Toolkit.i18nText("Fine-Design_Basic_Custom")});
uiComboBox.setSize(new Dimension(headerAreaPaneRightWidth, AbstractSortPane.PANE_COMPONENT_HEIGHT));
uiComboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() != uiComboBox.getSelectedIndex()) {
setSortColumnRowPaneShow(uiComboBox.getSelectedIndex() == 1);
}
}
});
uiComboBox.setEnabled(false);
}
void setSortColumnRowPaneShow(boolean show) {
if (show) {
jLayeredPane.setLayer(columnRowPane, JLayeredPane.POPUP_LAYER);
jLayeredPane.setLayer(uiComboBox, JLayeredPane.MODAL_LAYER);
if (!populateBeaning) {
ColumnRow columnRow = columnRowPane.updateBean();
if (cellSelectionManager.isNotSelectables(columnRow)) {
columnRowPane.setColumnRow(ColumnRow.ERROR);
} else {
cellSelectionManager.addNotSelectables(columnRow);
}
}
} else {
jLayeredPane.setLayer(uiComboBox, JLayeredPane.POPUP_LAYER);
jLayeredPane.setLayer(columnRowPane, JLayeredPane.MODAL_LAYER);
if (!populateBeaning) {
cellSelectionManager.removeNotSelectables(columnRowPane.updateBean());
}
}
refresh();
}
void initJLayeredPane() {
jLayeredPane = new JLayeredPane();
columnRowPane = new SortColumnRowPane(headerAreaPaneRightWidth - 18, AbstractSortPane.PANE_COMPONENT_HEIGHT);
jLayeredPane.setPreferredSize(new Dimension(headerAreaPaneRightWidth, AbstractSortPane.PANE_COMPONENT_HEIGHT));
jLayeredPane.add(columnRowPane, JLayeredPane.MODAL_LAYER);
jLayeredPane.add(uiComboBox, JLayeredPane.POPUP_LAYER);
this.add(jLayeredPane);
}
public void populateBean(ColumnRow columnRow, boolean showHeaderArea, boolean enabled) {
populateBeaning = true;
cellSelectionManager.build();
columnRowPane.populateBean(columnRow, enabled, cellSelectionManager);
if (showHeaderArea) {
uiComboBox.setSelectedIndex(1);
} else {
uiComboBox.setSelectedIndex(0);
}
uiComboBox.setEnabled(enabled);
populateBeaning = false;
}
public ColumnRow updateBean() {
if (uiComboBox.getSelectedIndex() == 0) {
return null;
} else {
return columnRowPane.updateBean();
}
}
public void refresh() {
validate();
repaint();
revalidate();
}
}
public static class CellSelectionManager {
ElementCasePane elementCase;
java.util.List<ColumnRow> notSelectables = new ArrayList<>();
void build() {
ElementCasePane elementCase = SortColumnRowPane.getCurrentElementCase();
if (elementCase != null && this.elementCase != elementCase) {
this.elementCase = elementCase;
notSelectables = new ArrayList<>();
buildNotSelectables(elementCase.getEditingElementCase());
}
}
public java.util.List<ColumnRow> getNotSelectables() {
return this.notSelectables;
}
public boolean isNotSelectables(ColumnRow columnRow) {
return notSelectables != null && notSelectables.contains(columnRow);
}
public void addNotSelectables(ColumnRow columnRow) {
if (columnRow != null) {
removeNotSelectables(columnRow);
notSelectables.add(columnRow);
}
}
public void removeNotSelectables(ColumnRow columnRow) {
notSelectables.remove(columnRow);
}
private void buildNotSelectables(TemplateElementCase elementCase) {
Iterator iterator = elementCase.cellIterator();
while (iterator.hasNext()) {
TemplateCellElement templateCellElement = (TemplateCellElement) iterator.next();
CellExpandAttr cellExpandAttr = templateCellElement.getCellExpandAttr();
if (cellExpandAttr != null) {
handleDisableHeaderCell(cellExpandAttr);
}
Object value = templateCellElement.getValue();
if (value instanceof DSColumn) {
handleDisableHeaderCell((DSColumn) value);
}
}
}
private void handleDisableHeaderCell(CellSortable cellSortable) {
if (cellSortable.getCellSortAttr() != null) {
SortHeader sortHeader = cellSortable.getCellSortAttr().getSortHeader();
if (sortHeader != null) {
String headerArea = sortHeader.getHeaderArea();
if (headerArea != null) {
ColumnRow headerColumnRow = ColumnRow.valueOf(headerArea);
addNotSelectables(headerColumnRow);
}
}
}
}
}
}

81
designer-realize/src/main/java/com/fr/design/sort/header/HeaderSettingPane.java

@ -0,0 +1,81 @@
package com.fr.design.sort.header;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.sort.common.AbstractSortPane;
import com.fr.report.core.sort.header.SortHeader;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
public class HeaderSettingPane extends JPanel {
protected int headerSettingPaneWidth;
protected int headerSettingPaneRightWidth;
HeaderSortRulePane headerSortRulePane;
UICheckBox uiCheckBox;
HeaderSettingPane(int headerSettingPaneWidth, int headerSettingPaneRightWidth) {
this.headerSettingPaneWidth = headerSettingPaneWidth;
this.headerSettingPaneRightWidth = headerSettingPaneRightWidth;
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
initComponents();
}
void initComponents() {
initUILabel();
initHeaderSortRulePane();
}
void initUILabel() {
JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 2));
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Header_Setting"));
UILabel emptyUILabel = new UILabel();
emptyUILabel.setPreferredSize(new Dimension(10, 10));
uiCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Sort_Allow_User_Click_Sort_Order"));
uiCheckBox.setPreferredSize(new Dimension(headerSettingPaneRightWidth - 10, AbstractSortPane.PANE_COMPONENT_HEIGHT));
uiCheckBox.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
headerSortRulePane.setVisible(uiCheckBox.isSelected());
}
});
jPanel.add(uiLabel);
jPanel.add(emptyUILabel);
jPanel.add(uiCheckBox);
this.add(jPanel);
}
void initHeaderSortRulePane() {
headerSortRulePane = new HeaderSortRulePane();
this.add(headerSortRulePane);
headerSortRulePane.setVisible(false);
}
protected void refresh() {
validate();
repaint();
revalidate();
}
public void populateBean(SortHeader.SortItem[] sortItems) {
if (sortItems == null) {
uiCheckBox.setSelected(false);
} else {
uiCheckBox.setSelected(true);
}
headerSortRulePane.populateBean(sortItems);
}
public SortHeader.SortItem[] updateBean() {
if (uiCheckBox.isSelected()) {
return headerSortRulePane.updateBean();
} else {
return null;
}
}
}

279
designer-realize/src/main/java/com/fr/design/sort/header/HeaderSortRulePane.java

@ -0,0 +1,279 @@
package com.fr.design.sort.header;
import com.fr.base.svg.SVGIcon;
import com.fr.base.svg.SVGTranscoder;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.theme.edit.ui.ColorListPane;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.report.core.sort.header.SortHeader;
import com.fr.report.core.sort.common.SortRule;
import org.apache.batik.transcoder.TranscoderInput;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class HeaderSortRulePane extends JPanel {
private static final String ASC_ICON_TEMPLATE_PATH = "/com/fr/design/images/sort/asc.svg";
private static final String DES_ICON_TEMPLATE_PATH = "/com/fr/design/images/sort/des.svg";
private static final String NOSORT_ICON_TEMPLATE_PATH = "/com/fr/design/images/sort/nosort.svg";
private static final double ICON_SCALE = SVGIcon.SYSTEM_SCALE * 1.25;
private static final int ICON_LENGTH = (int) Math.ceil(16 * ICON_SCALE);
IconButton ascIconButton;
IconButton desIconButton;
IconButton nosortIconButton;
UICheckBox ascUICheckBox;
UICheckBox desUICheckBox;
UICheckBox nosortUICheckBox;
static Map<String, String> originalSvgTextMap = new HashMap<>();
HeaderSortRulePane() {
initComponents();
initState(true);
this.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15));
}
void initComponents() {
this.setLayout(new BorderLayout());
initUILabel();
initSortRuleItem();
this.setPreferredSize(new Dimension(160, 160));
}
void initUILabel() {
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Header_Sort_Basis"), SwingConstants.LEFT);
this.add(uiLabel, BorderLayout.NORTH);
}
void initSortRuleItem() {
Component[][] components = new Component[][]{
new Component[]{ascUICheckBox = new UICheckBox(SortRule.ASC.getDescription()), ascIconButton = new IconButton(ASC_ICON_TEMPLATE_PATH)},
new Component[]{desUICheckBox = new UICheckBox(SortRule.DES.getDescription()), desIconButton = new IconButton(DES_ICON_TEMPLATE_PATH)},
new Component[]{nosortUICheckBox = new UICheckBox(SortRule.NO_SORT.getDescription()), nosortIconButton = new IconButton(NOSORT_ICON_TEMPLATE_PATH)},
};
double[] rowSize = {ICON_LENGTH + 10, ICON_LENGTH + 10, ICON_LENGTH + 10};
double[] columnSize = {80, ICON_LENGTH + 10};
JPanel sortRuleItem = TableLayoutHelper.createCommonTableLayoutPane(components, rowSize, columnSize, 0);
this.add(sortRuleItem, BorderLayout.CENTER);
initUICheckBoxChange(ascUICheckBox, ascIconButton);
initUICheckBoxChange(desUICheckBox, desIconButton);
initUICheckBoxChange(nosortUICheckBox, nosortIconButton);
}
void initUICheckBoxChange(UICheckBox uiCheckBox, IconButton iconButton) {
uiCheckBox.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
iconButton.setActiveState(uiCheckBox.isSelected());
}
});
}
void initState(boolean selected) {
ascUICheckBox.setSelected(selected);
desUICheckBox.setSelected(selected);
nosortUICheckBox.setSelected(selected);
ascIconButton.refreshIconLabelColor(new Color(33, 33, 34));
desIconButton.refreshIconLabelColor(new Color(33, 33, 34));
nosortIconButton.refreshIconLabelColor(new Color(33, 33, 34));
}
class IconButton extends JPanel implements UIObserver {
JLayeredPane jLayeredPane;
String iconTemplatePath;
UILabel iconLabel;
ColorListPane.ColorButton colorButton;
Color color;
BufferedImage bufferedImage;
UIObserverListener uiObserverListener;
boolean activeState;
UILabel borderUiLabel;
IconButton(String iconTemplatePath) {
this.iconTemplatePath = iconTemplatePath;
initComponents();
}
public boolean isActiveState() {
return activeState;
}
public void setActiveState(boolean activeState) {
if (activeState) {
borderUiLabel.setBorder(BorderFactory.createLineBorder(Color.gray, 1));
colorButton.setVisible(true);
} else {
borderUiLabel.setBorder(null);
colorButton.setVisible(false);
}
this.activeState = activeState;
}
void initComponents() {
jLayeredPane = new JLayeredPane();
iconLabel = getIconLabel(iconTemplatePath);
borderUiLabel = new UILabel();
borderUiLabel.setSize(ICON_LENGTH, ICON_LENGTH);
borderUiLabel.setOpaque(true);
borderUiLabel.setBackground(Color.WHITE);
iconLabel.setSize(ICON_LENGTH, ICON_LENGTH);
colorButton = new ColorListPane.ColorButton(Color.CYAN);
colorButton.setSize(ICON_LENGTH, ICON_LENGTH);
colorButton.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
color = colorButton.getSelectObject();
refreshIconLabelColor(color);
uiObserverListener.doChange();
}
});
jLayeredPane.setPreferredSize(new Dimension(ICON_LENGTH, ICON_LENGTH));
jLayeredPane.add(iconLabel, JLayeredPane.POPUP_LAYER);
jLayeredPane.add(borderUiLabel, JLayeredPane.MODAL_LAYER);
jLayeredPane.add(colorButton, JLayeredPane.PALETTE_LAYER);
this.add(jLayeredPane);
}
void refreshIconLabelColor(Color color) {
Icon icon = getIcon(iconTemplatePath, color);
refreshIconLabel(icon);
}
void refreshIconLabel(BufferedImage bufferedImage) {
if (bufferedImage != null) {
this.bufferedImage = bufferedImage;
Icon icon = new SVGIcon(bufferedImage);
refreshIconLabel(icon);
}
}
void refreshIconLabel(Icon icon) {
if (icon != null) {
iconLabel.removeAll();
iconLabel.setIcon(icon);
iconLabel.repaint();
}
}
UILabel getIconLabel(String iconPath) {
return getIconLabel(iconPath, new Color(33, 33, 34));
}
UILabel getIconLabel(String iconPath, Color color) {
Icon svgIcon = getIcon(iconPath, color);
return new UILabel(svgIcon);
}
Icon getIcon(String iconPath, Color color) {
try {
String originalSvgText = getOriginalSvgText(iconPath);
String svgText = originalSvgText.replaceAll("\\{fillColor\\}", shiftColor(color));
InputStream svgInputStream = new ByteArrayInputStream(svgText.getBytes(StandardCharsets.UTF_8));
TranscoderInput input = new TranscoderInput(svgInputStream);
bufferedImage = SVGTranscoder.createImage(ICON_SCALE, input).getImage();
SVGIcon svgIcon = new SVGIcon(bufferedImage);
return svgIcon;
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
return null;
}
String getOriginalSvgText(String iconPath) throws Exception {
String originalSvgText = originalSvgTextMap.get(iconPath);
if (originalSvgText == null) {
InputStream inputStream = IOUtils.getResourceAsStream(iconPath, HeaderSortRulePane.class);
originalSvgText = getSvgText(inputStream);
originalSvgTextMap.put(iconPath, originalSvgText);
}
return originalSvgText;
}
String shiftColor(Color color) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(shiftValue(color.getRed()));
stringBuilder.append(shiftValue(color.getGreen()));
stringBuilder.append(shiftValue(color.getBlue()));
return stringBuilder.toString();
}
String shiftValue(int value) {
String resultValue = Integer.toHexString(value);
if (resultValue.length() == 1) {
resultValue = "0" + resultValue;
}
return resultValue;
}
private String getSvgText(InputStream inputStream) throws Exception {
StringBuffer stringBuffer = new StringBuffer();
byte[] b = new byte[1024];
for (int n; (n = inputStream.read(b)) != -1; ) {
stringBuffer.append(new String(b, 0, n));
}
return stringBuffer.toString();
}
@Override
public void registerChangeListener(UIObserverListener uiObserverListener) {
this.uiObserverListener = uiObserverListener;
}
@Override
public boolean shouldResponseChangeListener() {
return true;
}
}
public void populateBean(SortHeader.SortItem[] sortItems) {
initState(sortItems == null);
if (sortItems != null) {
for (SortHeader.SortItem sortItem : sortItems) {
SortRule sortRule = sortItem.getSortRule();
BufferedImage bufferedImage = sortItem.getBufferedImage();
if (sortRule == SortRule.ASC) {
ascIconButton.refreshIconLabel(bufferedImage);
ascUICheckBox.setSelected(true);
} else if (sortRule == SortRule.DES) {
desIconButton.refreshIconLabel(bufferedImage);
desUICheckBox.setSelected(true);
} else if (sortRule == SortRule.NO_SORT) {
nosortIconButton.refreshIconLabel(bufferedImage);
nosortUICheckBox.setSelected(true);
}
}
}
}
public SortHeader.SortItem[] updateBean() {
java.util.List<SortHeader.SortItem> items = new ArrayList<>();
if (ascUICheckBox.isSelected()) {
items.add(new SortHeader.SortItem(SortRule.ASC, ascIconButton.bufferedImage));
}
if (desUICheckBox.isSelected()) {
items.add(new SortHeader.SortItem(SortRule.DES, desIconButton.bufferedImage));
}
if (nosortUICheckBox.isSelected()) {
items.add(new SortHeader.SortItem(SortRule.NO_SORT, nosortIconButton.bufferedImage));
}
SortHeader.SortItem[] resultItems = new SortHeader.SortItem[items.size()];
return items.toArray(resultItems);
}
}

65
designer-realize/src/main/java/com/fr/design/sort/header/SortHeaderPane.java

@ -0,0 +1,65 @@
package com.fr.design.sort.header;
import com.fr.design.sort.common.SortColumnRowPane;
import com.fr.report.cell.TemplateCellElement;
import com.fr.report.core.sort.header.SortHeader;
import com.fr.stable.ColumnRow;
import javax.swing.*;
public class SortHeaderPane extends JPanel {
int sortHeaderPaneWidth;
int sortHeaderPaneRightWidth;
SortHeader sortHeader;
HeaderAreaPane headerAreaPane;
HeaderSettingPane headerSettingPane;
TemplateCellElement cellElement;
public SortHeaderPane(int sortHeaderPaneWidth, int sortHeaderPaneRightWidth) {
this.sortHeaderPaneWidth = sortHeaderPaneWidth;
this.sortHeaderPaneRightWidth = sortHeaderPaneRightWidth;
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
initHeaderArea();
initHeaderSetting();
this.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
}
void initHeaderArea() {
this.headerAreaPane = new HeaderAreaPane(sortHeaderPaneWidth, sortHeaderPaneRightWidth);
this.add(headerAreaPane);
}
void initHeaderSetting() {
this.headerSettingPane = new HeaderSettingPane(sortHeaderPaneWidth, sortHeaderPaneRightWidth);
this.add(headerSettingPane);
}
public void populateBean(SortHeader sortHeader, String defaultHeaderArea) {
this.sortHeader = sortHeader;
boolean showHeaderArea = false;
SortHeader.SortItem[] sortItems = null;
String headerArea = defaultHeaderArea;
ColumnRow columnRow = ColumnRow.valueOf(headerArea);
if (sortHeader != null) {
headerArea = sortHeader.getHeaderArea();
sortItems = sortHeader.getSortItems();
if (headerArea != null) {
showHeaderArea = true;
columnRow = ColumnRow.valueOf(headerArea);
}
}
headerAreaPane.populateBean(columnRow, showHeaderArea);
headerSettingPane.populateBean(sortItems);
}
public SortHeader updateBean(TemplateCellElement cellElement) {
ColumnRow columnRow = headerAreaPane.updateBean( cellElement);
SortHeader.SortItem[] items = headerSettingPane.updateBean();
String headerArea = null;
if (columnRow != null) {
headerArea = columnRow.toString();
}
SortHeader sortHeader = new SortHeader(headerArea, null, items);
return sortHeader;
}
}

367
designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellDSColumnEditor.java

@ -11,6 +11,7 @@ import com.fr.design.dscolumn.DSColumnAdvancedPane;
import com.fr.design.dscolumn.ResultSetGroupDockingPane;
import com.fr.design.dscolumn.SelectedDataColumnPane;
import com.fr.design.event.UIObserverListener;
import com.fr.design.foldablepane.UIExpandablePane;
import com.fr.design.formula.CustomVariableResolver;
import com.fr.design.formula.FormulaFactory;
import com.fr.design.formula.UIFormula;
@ -31,6 +32,7 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.cell.AbstractDSCellEditorPane;
import com.fr.design.sort.celldscolumn.CellDSColumnSortPane;
import com.fr.design.utils.gui.UIComponentUtils;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.general.IOUtils;
@ -221,62 +223,6 @@ public class CellDSColumnEditor extends CellQuickEditor {
*/
private UIButton conditionUIButton;
/**
* 分组设置监听器
*/
private ItemListener groupListener = new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e == null) {
//分组-高级-自定义点确定的时候传进来null的e,但是这时候应该触发保存
groupPane.update();
fireTargetModified();
return;
}
if (e.getStateChange() == ItemEvent.DESELECTED) {
groupPane.update();
fireTargetModified();
}
}
};
/**
* 数据集列设置监听器
*/
private ItemListener dataListener = new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
dataPane.update(cellElement);
fireTargetModified();
}
}
};
DSColumnBasicEditorPane() {
dataPane = new SelectedDataColumnPane(true, true);
groupPane = new ResultSetGroupDockingPane();
dataPane.setListener(dataListener);
groupPane.setListener(groupListener);
double[] rowSize = {P}, columnSize = {60, F};
UILabel uiLabel = FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Report_Filter_Conditions"));
condition = new DSColumnConditionAction();
if (tc != null) {
condition.setEditingComponent(tc);
}
//丢掉icon,修改按钮名称为编辑
condition.setSmallIcon(UIConstants.EMPTY_ICON);
condition.setName(Toolkit.i18nText("Fine-Design_Basic_Edit"));
conditionUIButton = new UIButton(condition);
Component[][] components = new Component[][]{
new Component[]{uiLabel, UIComponentUtils.wrapWithBorderLayoutPane(conditionUIButton)}
};
conditionPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, HGAP, VGAP);
this.createScrollPane();
this.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
}
@Override
public String getIconPath() {
@ -297,11 +243,13 @@ public class CellDSColumnEditor extends CellQuickEditor {
@Override
public void populate() {
this.removeAttributeChangeListener();
dataPane.populate(DesignTableDataManager.getEditingTableDataSource(), cellElement, tc);
groupPane.populate(cellElement);
if (tc != null) {
condition.setEditingComponent(tc);
}
this.addAttributeChangeListener();
}
@Override
@ -318,7 +266,7 @@ public class CellDSColumnEditor extends CellQuickEditor {
*/
@Override
protected JPanel createContentPane() {
initComponents();
double[] columnSize = {F};
double[] rowSize = {P, P, P};
Component[][] components = new Component[][]{
@ -331,16 +279,43 @@ public class CellDSColumnEditor extends CellQuickEditor {
};
return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, HGAP, VGAP);
}
private void initComponents(){
dataPane = new SelectedDataColumnPane(true, true);
groupPane = new ResultSetGroupDockingPane();
double[] rowSize = {P}, columnSize = {60, F};
UILabel uiLabel = FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Report_Filter_Conditions"));
condition = new DSColumnConditionAction();
if (tc != null) {
condition.setEditingComponent(tc);
}
//丢掉icon,修改按钮名称为编辑
condition.setSmallIcon(UIConstants.EMPTY_ICON);
condition.setName(Toolkit.i18nText("Fine-Design_Basic_Edit"));
conditionUIButton = new UIButton(condition);
Component[][] components = new Component[][]{
new Component[]{uiLabel, UIComponentUtils.wrapWithBorderLayoutPane(conditionUIButton)}
};
conditionPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, HGAP, VGAP);
this.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
}
@Override
protected AttributeChangeListener getAttributeChangeListener() {
return new AttributeChangeListener() {
@Override
public void attributeChange() {
update();
fireTargetModified();
}
};
}
}
class DSColumnAdvancedEditorPane extends AbstractDSCellEditorPane {
/*pane begin*/
/**
* 排列顺序
*/
private ResultSetSortConfigPane sortPane;
/**
* 结果集筛选
*/
@ -373,88 +348,13 @@ public class CellDSColumnEditor extends CellQuickEditor {
* 补充空白数据数目面板 可隐藏
*/
private JPanel multiPane;
/*pane end*/
/*listeners begin*/
private UIObserverListener sortPaneFormulaChangeListener = new UIObserverListener() {
@Override
public void doChange() {
sortPane.update(cellElement);
fireTargetModified();
}
};
private ChangeListener sortTypeBtnGroupChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
sortPane.update(cellElement);
fireTargetModified();
}
};
private UIObserverListener filterPaneChangeListener = new UIObserverListener() {
@Override
public void doChange() {
filterPane.update(cellElement);
fireTargetModified();
}
};
private UIObserverListener customValuePaneChangeListener = new UIObserverListener() {
@Override
public void doChange() {
valuePane.update(cellElement);
fireTargetModified();
}
};
private AttributeChangeListener formatChangeListener = new AttributeChangeListener() {
@Override
public void attributeChange() {
formatAttrPane.update(cellElement);
fireTargetModified();
}
};
private ChangeListener heCheckBoxChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
cellDSColumnAdvancedPane.updateExtendConfig();
fireTargetModified();
}
};
private ChangeListener veCheckBoxChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
cellDSColumnAdvancedPane.updateExtendConfig();
fireTargetModified();
}
};
private ActionListener useMultiNumCheckBoxChangeListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
checkButtonEnabled();
cellDSColumnAdvancedPane.updateMultipleConfig();
fireTargetModified();
}
};
private ChangeListener multiNumSpinnerChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
cellDSColumnAdvancedPane.updateMultipleConfig();
fireTargetModified();
}
};
/*listeners end*/
private CellDSColumnSortPane cellDSColumnSortPane;
/*pane end*/
public DSColumnAdvancedEditorPane() {
this.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
this.createScrollPane();
}
@ -469,10 +369,10 @@ public class CellDSColumnEditor extends CellQuickEditor {
}
@Override
public void update() {
if (cellElement != null) {
sortPane.update(cellElement);
valuePane.update(cellElement);
formatAttrPane.update(cellElement);
filterPane.update(cellElement);
@ -480,14 +380,14 @@ public class CellDSColumnEditor extends CellQuickEditor {
updateExtendConfig();
//更新补充空白设置
updateMultipleConfig();
cellDSColumnSortPane.updateBean(cellElement);
}
}
@Override
public void populate() {
if (cellElement != null) {
disableListener();
sortPane.populate(cellElement);
this.removeAttributeChangeListener();
valuePane.populate(cellElement);
formatAttrPane.populate(cellElement);
filterPane.populate(cellElement);
@ -524,8 +424,11 @@ public class CellDSColumnEditor extends CellQuickEditor {
useMultiNumCheckBox.setSelected(true);
multiNumSpinner.setValue(cellExpandAttr.getMultipleNumber());
}
if (cellDSColumnSortPane != null) {
cellDSColumnSortPane.populateBean(cellElement);
}
this.checkButtonEnabled();
enableListener();
this.addAttributeChangeListener();
}
}
@ -534,6 +437,17 @@ public class CellDSColumnEditor extends CellQuickEditor {
}
@Override
protected AttributeChangeListener getAttributeChangeListener() {
return new AttributeChangeListener() {
@Override
public void attributeChange() {
update();
fireTargetModified();
}
};
}
/**
* 更新单元格扩展属性
*/
@ -578,11 +492,8 @@ public class CellDSColumnEditor extends CellQuickEditor {
*/
@Override
protected JPanel createContentPane() {
JPanel contentPane = new JPanel(new BorderLayout());
this.setLayout(FRGUIPaneFactory.createBorderLayout());
//结果集排序
sortPane = new ResultSetSortConfigPane();
//结果筛选
filterPane = new ResultSetFilterConfigPane();
@ -616,10 +527,7 @@ public class CellDSColumnEditor extends CellQuickEditor {
multiPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0));
multiNumPane.add(multiPane);
enableListener();
Component[][] components = new Component[][]{
{sortPane},
{filterPane},
{valuePane},
{formatAttrPane},
@ -630,32 +538,15 @@ public class CellDSColumnEditor extends CellQuickEditor {
double[] rowSize = new double[components.length];
Arrays.fill(rowSize, P);
double[] columnSize = {F};
return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, HGAP, VGAP);
}
public void enableListener() {
sortPane.addListener(sortPaneFormulaChangeListener, sortTypeBtnGroupChangeListener);
filterPane.addListener(filterPaneChangeListener);
valuePane.addListener(customValuePaneChangeListener);
formatAttrPane.addAttributeChangeListener(formatChangeListener);
heCheckBox.addChangeListener(heCheckBoxChangeListener);
veCheckBox.addChangeListener(veCheckBoxChangeListener);
useMultiNumCheckBox.addActionListener(useMultiNumCheckBoxChangeListener);
multiNumSpinner.addChangeListener(multiNumSpinnerChangeListener);
}
public void disableListener() {
sortPane.removeListener(sortTypeBtnGroupChangeListener);
filterPane.removeListener();
valuePane.removeListener();
heCheckBox.removeChangeListener(heCheckBoxChangeListener);
veCheckBox.removeChangeListener(veCheckBoxChangeListener);
useMultiNumCheckBox.removeActionListener(useMultiNumCheckBoxChangeListener);
multiNumSpinner.removeChangeListener(multiNumSpinnerChangeListener);
JPanel advancePropertyPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, HGAP, VGAP);
contentPane.add(advancePropertyPane, BorderLayout.NORTH);
UIExpandablePane sortUIExpandablePane =
new UIExpandablePane(Toolkit.i18nText("Fine-Design_Sort_Data_Column_Sort"),
223, 24, cellDSColumnSortPane = new CellDSColumnSortPane());
contentPane.add(sortUIExpandablePane, BorderLayout.CENTER);
return contentPane;
}
private void checkButtonEnabled() {
if (useMultiNumCheckBox.isSelected()) {
multiNumSpinner.setEnabled(true);
@ -666,136 +557,6 @@ public class CellDSColumnEditor extends CellQuickEditor {
}
}
/**
* 单元格元素>数据集>高级设置>结果排序设置面板
*
* @see com.fr.design.expand.SortExpandAttrPane
* @see DSColumnAdvancedPane.SortPane
*/
public class ResultSetSortConfigPane extends JPanel {
private static final String DEFAULT_VALUE = "=";
private JPanel contentPane;
private UIButtonGroup sortTypePane;
private JFormulaField formulaField;
private CardLayout cardLayout;
private JPanel centerPane;
public ResultSetSortConfigPane() {
this.setLayout(new BorderLayout());
Icon[] iconArray = {
IOUtils.readIcon("/com/fr/design/images/expand/none16x16.png"),
IOUtils.readIcon("/com/fr/design/images/expand/asc.png"),
IOUtils.readIcon("/com/fr/design/images/expand/des.png")
};
String[] nameArray = {Toolkit.i18nText("Fine-Design_Report_Sort_Original"), Toolkit.i18nText("Fine-Design_Report_Sort_Ascending"), Toolkit.i18nText("Fine-Design_Report_Sort_Descending")};
sortTypePane = new UIButtonGroup(iconArray);
sortTypePane.setAllToolTips(nameArray);
sortTypePane.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_ExpandD_Sort_After_Expand"));
cardLayout = new CardLayout();
centerPane = new JPanel(cardLayout);
formulaField = new JFormulaField(DEFAULT_VALUE);
centerPane.add(new JPanel(), "none");
centerPane.add(formulaField, "content");
UILabel sortLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Sort_Sort_Order"));
sortLabel.setPreferredSize(LABEL_DIMENSION);
sortTypePane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
boolean noContent = sortTypePane.getSelectedIndex() == 0;
cardLayout.show(centerPane, noContent ? "none" : "content");
if (noContent) {
centerPane.setPreferredSize(new Dimension(0, 0));
TableLayoutHelper.modifyTableLayoutIndexVGap(contentPane, 2, 0);
} else {
centerPane.setPreferredSize(new Dimension(165, 20));
TableLayoutHelper.modifyTableLayoutIndexVGap(contentPane, 2, VGAP);
}
}
});
Component[][] components = new Component[][]{
new Component[]{sortLabel, sortTypePane},
new Component[]{null, centerPane}
};
double[] rowSize = {P, P}, columnSize = {P, F};
contentPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, HGAP, VGAP);
this.add(contentPane, BorderLayout.CENTER);
}
/**
* 刷新面板信息
*
* @param cellElement 单元格
*/
public void populate(TemplateCellElement cellElement) {
if (cellElement != null) {
Object value = cellElement.getValue();
if (value instanceof DSColumn) {
this.formulaField.populateElement(cellElement);
DSColumn dSColumn = (DSColumn) value;
int sort = dSColumn.getOrder();
this.sortTypePane.setSelectedIndex(sort);
boolean noContent = sortTypePane.getSelectedIndex() == 0;
cardLayout.show(centerPane, noContent ? "none" : "content");
if (noContent) {
centerPane.setPreferredSize(new Dimension(0, 0));
TableLayoutHelper.modifyTableLayoutIndexVGap(contentPane, 2, 0);
} else {
centerPane.setPreferredSize(new Dimension(156, 20));
TableLayoutHelper.modifyTableLayoutIndexVGap(contentPane, 2, VGAP);
}
String sortFormula = dSColumn.getSortFormula();
if (sortFormula != null && sortFormula.length() >= 1) {
this.formulaField.populate(sortFormula);
} else {
this.formulaField.populate(DEFAULT_VALUE);
}
}
}
}
/**
* 保存面板配置信息
*
* @param cellElement 单元格
*/
public void update(CellElement cellElement) {
if (cellElement != null) {
Object value = cellElement.getValue();
if (value instanceof DSColumn) {
DSColumn dSColumn = (DSColumn) value;
dSColumn.setOrder(this.sortTypePane.getSelectedIndex());
dSColumn.setSortFormula(this.formulaField.getFormulaText());
}
}
}
/**
* 添加事件监听器
*
* @param formulaChangeListener 公式输入框改动事件监听器
* @param changeListener 排序类型下拉框改动事件监听器
*/
public void addListener(UIObserverListener formulaChangeListener, ChangeListener changeListener) {
formulaField.addListener(formulaChangeListener);
sortTypePane.addChangeListener(changeListener);
}
/**
* 去除事件监听器
*
* @param changeListener 排序类型下拉框改动事件监听器
*/
public void removeListener(ChangeListener changeListener) {
formulaField.removeListener();
sortTypePane.removeChangeListener(changeListener);
}
}
/**
* 单元格元素>数据集>高级设置>结果集筛选设置面板
*

4
designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

@ -10,6 +10,7 @@ import com.fr.base.theme.migrator.FormThemeConfigMigrator;
import com.fr.base.theme.migrator.ReportThemeConfigMigrator;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.config.MarketConfig;
import com.fr.config.ServerPreferenceConfig;
import com.fr.decision.update.backup.RecoverManager;
import com.fr.design.DesignerEnvManager;
import com.fr.design.ExtraDesignClassManager;
@ -187,6 +188,9 @@ public class DesignerActivator extends Activator implements Prepare {
//生成BasicChartQuickEditor对象,需要用到ChartDesignerActivator的注册信息(DesignModuleFactory.registerChartPropertyPaneClass(ChartPropertyPane.class);)
//所以不能在registerCellEditor函数中进行注册
ActionFactory.registerCellEditor(ChartCollection.class, new BasicChartQuickEditor());
if (DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter() && WorkContext.getCurrent().isLocal()) {
ServerPreferenceConfig.getInstance().setUseOptimizedUPM(DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter());
}
}
private void loadLogAppender() {

Loading…
Cancel
Save