Browse Source

Merge pull request #12511 in DESIGN/design from release/11.0 to bugfix/11.0

* commit 'e6acc1406f2bced1b8730a738fd4ce754c484cdd': (57 commits)
  REPORT-98345 版本管理三期 迁移成功后,没刷新工具栏
  REPORT-100958 【版本管理三期】还原或者预览版本,弹窗应该关闭 修改方法名
  REPORT-100958 【版本管理三期】还原或者预览版本,弹窗应该关闭 修改方法名
  REPORT-100458 【版本管理二期】迁移弹窗,保留版本的输入框没有非法值校验
  REPORT-100958 【版本管理三期】还原或者预览版本,弹窗应该关闭
  REPORT-100958 【版本管理三期】还原或者预览版本,弹窗应该关闭
  REPORT-91839 模板版本管理二期 没设置启动页,启动的时候判断有点问题
  REPORT-100518 【版本管理二期】无磁盘写入权限,版本迁移无异常提示
  REPORT-101340 【版本管理二期】自动清理配置灰化时,hover提示没有
  REPORT-101060 【版本管理三期】删除无权限的版本,能删除成功
  REPORT-101166 【版本管理三期】集群环境,版本管理页面所有配置项都不可点
  REPORT-100954 【版本管理三期】版本中心弹窗交互问题
  REPORT-91839 模板版本管理二期 偶遇报错,不确定场景,加一下处理
  REPORT-101167 【版本管理一期】集群环境,保存版本不生效
  REPORT-100162 【版本管理二期】模板不在编辑状态,还是在触发自动保存
  REPORT-100633 【版本管理二期】取消勾选备注的版本不会被清理,备注的版本还是不会被清理
  REPORT-101289 【版本管理二期】数据迁移的提示弹窗位置没有居中
  REPORT-101293 【版本管理二期】模板未打开,点击版本管理点不开
  fix: 只有选择关闭当前分类其它模板时才做类型比较 #REPORT-99959
  fix: 关闭当前类型模板时,不判断其它类型模板是否保存 #REPORT-99959
  ...
bugfix/11.0
superman 1 year ago
parent
commit
35143aad51
  1. 82
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  2. 20
      designer-base/src/main/java/com/fr/design/dialog/BasicPane.java
  3. 10
      designer-base/src/main/java/com/fr/design/editor/editor/NumberEditor.java
  4. 2
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java
  5. 19
      designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java
  6. 13
      designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java
  7. 75
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  8. 4
      designer-base/src/main/java/com/fr/design/mainframe/vcs/RecycleAction.java
  9. 37
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsExceptionUtils.java
  10. 291
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsOperatorWorker.java
  11. 49
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsRecycleSettingHelper.java
  12. 162
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsService.java
  13. 9
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsTableEntity.java
  14. 33
      designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java
  15. 32
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/AbstractSupportSelectTablePane.java
  16. 120
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecyclePane.java
  17. 103
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecycleSettingPane.java
  18. 32
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/ToolTipTableCellRenderer.java
  19. 59
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/UIPositiveIntEditor.java
  20. 39
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/UIPositiveIntSpinner.java
  21. 156
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsBatchProcessDetailPane.java
  22. 35
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCellEditor.java
  23. 29
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCellRender.java
  24. 38
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCenterPane.java
  25. 95
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsMovePanel.java
  26. 21
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsNewPane.java
  27. 37
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsOperatorPane.java
  28. 81
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsProgressDialog.java
  29. 13
      designer-base/src/main/java/com/fr/design/mainframe/widget/editors/DataBindingEditor.java
  30. 20
      designer-base/src/main/java/com/fr/design/mainframe/widget/editors/WidgetValueEditor.java
  31. 4
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_sort_normal.svg
  32. 27
      designer-form/src/main/java/com/fr/design/designer/creator/XEditorHolder.java
  33. 23
      designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java
  34. 2
      designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java
  35. 2
      designer-form/src/main/java/com/fr/design/widget/ui/designer/component/FormWidgetValuePane.java

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

@ -36,6 +36,7 @@ import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.mainframe.vcs.ui.UIPositiveIntEditor;
import com.fr.design.mainframe.vcs.ui.VcsMovePanel;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.unit.UnitConvertUtil;
@ -64,6 +65,8 @@ import com.fr.workspace.server.vcs.VcsConfig;
import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.workspace.server.vcs.git.config.GcConfig;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanOperator;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanSchedule;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanService;
import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory;
@ -177,6 +180,8 @@ public class PreferencePane extends BasicPane {
private static final int DEFAULT_INDEX = 3;
private BasicDialog basicDialog;
private boolean languageChanged; // 是否修改了设计器语言设置
//设置是否支持undo
private UICheckBox supportUndoCheckBox;
@ -221,7 +226,7 @@ public class PreferencePane extends BasicPane {
private UIComboBox autoCleanIntervalComboBox;
private UIComboBox autoCleanRetainIntervalComboBox;
private IntegerEditor autoSaveIntervalEditor;
private UIPositiveIntEditor autoSaveIntervalEditor;
private UICheckBox saveCommitCheckBox;
private UICheckBox useIntervalCheckBox;
private VcsMovePanel movePanel;
@ -231,7 +236,7 @@ public class PreferencePane extends BasicPane {
private JPanel gcControlPane;
private UICheckBox startupPageEnabledCheckBox;
private IntegerEditor saveIntervalEditor;
private UIPositiveIntEditor saveIntervalEditor;
private UICheckBox gcEnableCheckBox;
private UIButton gcButton;
private UILabel remindVcsLabel;
@ -426,7 +431,7 @@ public class PreferencePane extends BasicPane {
saveIntervalPane = createSaveIntervalPane();
saveCommitCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_No_Delete"));
saveIntervalEditor = new IntegerEditor(60);
saveIntervalEditor = new UIPositiveIntEditor(60);
useIntervalCheckBox = new UICheckBox();
savePane.add(vcsEnableCheckBox);
savePane.add(saveIntervalPane);
@ -444,6 +449,7 @@ public class PreferencePane extends BasicPane {
intervalPanel.add(saveIntervalEditor);
intervalPanel.add(delayLabel);
autoCleanPane = createAutoCleanPane();
checkAutoScheduleStartAndUpdateStatus();
vcsEnableCheckBox.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
@ -465,10 +471,13 @@ public class PreferencePane extends BasicPane {
});
vcsPane.add(enableVcsPanel);
vcsPane.add(intervalPanel);
vcsPane.add(saveCommitCheckBox);
if (VcsHelper.getInstance().isLegacyMode()) {
vcsPane.add(saveCommitCheckBox);
}
vcsPane.add(autoCleanPane);
saveIntervalPane.setVisible(!VcsHelper.getInstance().isLegacyMode());
autoCleanPane.setVisible(!VcsHelper.getInstance().isLegacyMode());
boolean support = VcsHelper.getInstance().checkV2FunctionSupport();
saveIntervalPane.setVisible(support);
autoCleanPane.setVisible(support);
if (VcsHelper.getInstance().isLegacyMode()) {
// 老版本时才显示gc选项
vcsPane.add(gcControlPane);
@ -488,12 +497,13 @@ public class PreferencePane extends BasicPane {
saveIntervalPane.setVisible(useV2);
autoCleanPane.setVisible(useV2);
gcControlPane.setVisible(!useV2);
saveCommitCheckBox.setVisible(!useV2);
useVcsAutoCleanScheduleCheckBox.setSelected(useV2);
useVcsAutoSaveScheduleCheckBox.setSelected(useV2);
useVcsAutoCleanScheduleCheckBox.setEnabled(useV2 && FineScheduler.getInstance().isStarted());
checkAutoScheduleStartAndUpdateStatus();
useVcsAutoSaveScheduleCheckBox.setEnabled(useV2);
}
});
}, basicDialog);
};
private JPanel createAutoCleanPane() {
@ -509,15 +519,45 @@ public class PreferencePane extends BasicPane {
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Content")));
autoCleanPane.add(autoCleanRetainIntervalComboBox);
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Last")));
useVcsAutoCleanScheduleCheckBox.setEnabled(!VcsHelper.getInstance().isLegacyMode() && FineScheduler.getInstance().isStarted());
autoCleanPane.setVisible(false);
return autoCleanPane;
}
private void checkAutoScheduleStartAndUpdateStatus() {
if (!VcsHelper.getInstance().isLegacyMode()) {
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
return WorkContext.getCurrent().get(VcsAutoCleanOperator.class).isSupport();
}
@Override
protected void done() {
try {
boolean useAutoClean = get();
updateAutoCleanEnabled(useAutoClean);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}.execute();
} else {
updateAutoCleanEnabled(false);
}
}
private void updateAutoCleanEnabled(boolean b) {
useVcsAutoCleanScheduleCheckBox.setEnabled(b);
autoCleanIntervalComboBox.setEnabled(b);
autoCleanRetainIntervalComboBox.setEnabled(b);
if (autoCleanPane != null) {
autoCleanPane.setToolTipText(b ? null : Toolkit.i18nText("Fine-Design_Vcs_Server_Start_Hover"));
}
}
private JPanel createSaveIntervalPane() {
JPanel saveIntervalPane = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
useVcsAutoSaveScheduleCheckBox = new UICheckBox();
autoSaveIntervalEditor = new IntegerEditor(60);
autoSaveIntervalEditor = new UIPositiveIntEditor(60);
saveIntervalPane.add(useVcsAutoSaveScheduleCheckBox);
saveIntervalPane.add(new UILabel(i18nText("Fine-Design_Vcs_Every")));
saveIntervalPane.add(autoSaveIntervalEditor);
@ -909,7 +949,8 @@ public class PreferencePane extends BasicPane {
defaultStringToFormulaBox.setSelected(false);
}
VcsConfigManager vcsConfigManager = designerEnvManager.getVcsConfigManager();
if (WorkContext.getCurrent().isCluster()) {
//如果是集群并且是老版本则不可用
if (VcsHelper.getInstance().isLegacyMode() && WorkContext.getCurrent().isCluster()) {
vcsEnableCheckBox.setEnabled(false);
gcEnableCheckBox.setEnabled(false);
}
@ -1179,11 +1220,16 @@ public class PreferencePane extends BasicPane {
} else {
VcsHelper.getInstance().stopAutoSave();
}
if (useVcsAutoCleanScheduleCheckBox.isSelected()) {
FineLoggerFactory.getLogger().info("[VcsV2] start auto clean!");
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).addOrUpdateVcsAutoCleanJob(getDay(autoCleanIntervalComboBox.getSelectedIndex()));
} else {
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).stopVcsAutoCleanJob();
if (useVcsAutoCleanScheduleCheckBox.isEnabled()) {
if (useVcsAutoCleanScheduleCheckBox.isSelected()) {
FineLoggerFactory.getLogger().info("[VcsV2] start auto clean!");
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).addOrUpdateVcsAutoCleanJob(
VcsAutoCleanService.VCS_AUTO_CLEAN_JOB_NAME,
getDay(autoCleanIntervalComboBox.getSelectedIndex()),
VcsAutoCleanSchedule.class);
} else {
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).stopVcsAutoCleanJob(VcsAutoCleanService.VCS_AUTO_CLEAN_JOB_NAME);
}
}
}
return null;
@ -1219,12 +1265,14 @@ public class PreferencePane extends BasicPane {
@Override
public BasicDialog showWindow(Window window) {
return showWindow(window, new DialogActionAdapter() {
basicDialog = showWindow(window, new DialogActionAdapter() {
@Override
public void doOk() {
languageChanged = !ComparatorUtils.equals(languageComboBox.getSelectedItem(), DesignerEnvManager.getEnvManager(false).getLanguage());
}
});
movePanel.setParentDialog(basicDialog);
return basicDialog;
}
@Override

20
designer-base/src/main/java/com/fr/design/dialog/BasicPane.java

@ -75,6 +75,26 @@ public abstract class BasicPane extends JPanel {
return dg;
}
/**
* 显示小窗口并允许自定义需不需要按钮
*
* @param window 窗口
* @param isNeedButtonsPane 是否需要确定删除按钮
* @return 对话框
*/
public BasicDialog showSmallWindow(Window window, boolean isNeedButtonsPane) {
BasicDialog dg;
if (window instanceof Frame) {
dg = new DIALOG((Frame) window, isNeedButtonsPane);
} else {
dg = new DIALOG((Dialog) window, isNeedButtonsPane);
}
dg.setBasicDialogSize(BasicDialog.SMALL);
GUICoreUtils.centerWindow(dg);
dg.setResizable(false);
return dg;
}
/**
* 图表类型选择时 弹出的按钮大小, 不适合用最大最小, 因为图表大小 默认是规定好的, 那么界面大小也是必须配合.

10
designer-base/src/main/java/com/fr/design/editor/editor/NumberEditor.java

@ -38,7 +38,7 @@ public abstract class NumberEditor<T extends Number> extends Editor<T> {
*/
public NumberEditor(T value, String name) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
numberField = new UINumberField();
numberField = createNumberField();
this.add(numberField, BorderLayout.CENTER);
this.numberField.addKeyListener(textKeyListener);
this.numberField.setHorizontalAlignment(UITextField.RIGHT);
@ -46,6 +46,14 @@ public abstract class NumberEditor<T extends Number> extends Editor<T> {
this.setName(name);
}
/**
* 创建NumberField对象
*
*/
protected UINumberField createNumberField() {
return new UINumberField();
}
/**
* 给numberField加键盘事件
*

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

@ -419,7 +419,7 @@ public class MultiTemplateTabPane extends JComponent {
public void closeOtherByOperatorType(String operatorType){
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false);
if (saveSomeTempaltePane.showSavePane()) {
if (saveSomeTempaltePane.showSavePane(null, false, true)) {
List<JTemplate<?, ?>> openedTemplate = HistoryTemplateListCache.getInstance().getHistoryList();
JTemplate<?, ?>[] templates = new JTemplate<?, ?>[openedTemplate.size()];

19
designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java

@ -183,7 +183,19 @@ public class SaveSomeTemplatePane extends BasicPane {
* @return
*/
public boolean showSavePane(@Nullable MultiTemplateTabPane.CloseCondition option, boolean judgeJTemplateMustSave) {
initAndPopulate(option, judgeJTemplateMustSave);
return showSavePane(option, judgeJTemplateMustSave, false);
}
/**
* 显示保存模板提醒面板
*
* @param option 具体关闭操作
* @param judgeJTemplateMustSave 模板是否必须保存
* @param judgeSameTabType 是否只包含当前编辑的模板类型
* @return
*/
public boolean showSavePane(@Nullable MultiTemplateTabPane.CloseCondition option, boolean judgeJTemplateMustSave, boolean judgeSameTabType) {
initAndPopulate(option, judgeJTemplateMustSave, judgeSameTabType);
//如果有未保存的文件 ,则跳出保存对话框,选择要存储的项目
if (!unSavedTemplate.isEmpty()) {
dialog.setVisible(true);
@ -197,13 +209,16 @@ public class SaveSomeTemplatePane extends BasicPane {
return HistoryTemplateListPane.getInstance().getHistoryList();
}
private void initAndPopulate(@Nullable MultiTemplateTabPane.CloseCondition option, boolean judgeJTemplateMustSave) {
private void initAndPopulate(@Nullable MultiTemplateTabPane.CloseCondition option, boolean judgeJTemplateMustSave, boolean judgeSameTabType) {
java.util.List<JTemplate<?, ?>> opendedTemplate = getOpenedTemplatesToProcess();
JTemplate<?, ?> currentTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
int currentIndex = opendedTemplate.indexOf(currentTemplate);
for (int i = 0; i < opendedTemplate.size(); i++) {
//满足关闭条件的才继续判断文件是否发生了改动
boolean needClose = option == null || option.shouldClose(opendedTemplate.get(i), currentIndex, i);
if (judgeSameTabType) {
needClose &= ComparatorUtils.equals(opendedTemplate.get(i).getTemplateTabOperatorType(), currentTemplate.getTemplateTabOperatorType());
}
if (needClose && isneedToAdd(opendedTemplate.get(i), currentTemplate)) {
unSavedTemplate.add(opendedTemplate.get(i));
}

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

@ -18,7 +18,6 @@ import com.fr.design.lock.LockInfoDialog;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager;
import com.fr.design.mainframe.manager.search.searcher.control.pane.TemplateSearchRemindPane;
import com.fr.design.mainframe.vcs.VcsService;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.file.FILE;
import com.fr.file.FileNodeFILE;
@ -65,6 +64,7 @@ import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import com.fr.workspace.server.vcs.VcsOperator;
import org.jetbrains.annotations.Nullable;
@ -378,8 +378,6 @@ public class TemplateTreePane extends JPanel implements FileOperations {
deleteNodes(deletableNodes);
}
}
Set<FileNode> deletedFileNode = deletableNodes.stream().map(treeNode -> (FileNode) treeNode.getUserObject()).collect(Collectors.toSet());
refreshAfterDelete(deletedFileNode);
}
private void refreshAfterDelete(Set<FileNode> deletedPaths) {
@ -409,7 +407,12 @@ public class TemplateTreePane extends JPanel implements FileOperations {
if (node instanceof FileNode) {
FileNodeFILE nodeFILE = new FileNodeFILE((FileNode) node);
if (nodeFILE.exists()) {
VcsService.getInstance().doRecycle(VcsHelper.getInstance().dealWithFilePath(((FileNode) node).getEnvPath()));
try {
WorkContext.getCurrent().get(VcsOperator.class).recycleVersion(VcsHelper.getInstance().getCurrentUsername(), VcsHelper.getInstance().dealWithFilePath(((FileNode) node).getEnvPath()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error("[VcsV2] recycle {} failed", nodeFILE.getName());
return false;
}
if (TemplateResourceManager.getResource().delete(nodeFILE)) {
HistoryTemplateListCache.getInstance().deleteFile(nodeFILE);
} else {
@ -426,6 +429,8 @@ public class TemplateTreePane extends JPanel implements FileOperations {
if (!get()) {
showErrorDialog();
}
Set<FileNode> deletedFileNode = nodes.stream().map(treeNode -> (FileNode) treeNode.getUserObject()).collect(Collectors.toSet());
refreshAfterDelete(deletedFileNode);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}

75
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java

@ -46,6 +46,7 @@ import com.fr.design.roleAuthority.RolesAlreadyEditedPane;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.worker.save.CallbackSaveWorker;
import com.fr.event.Event;
import com.fr.file.filetree.FileNode;
import com.fr.general.ComparatorUtils;
@ -337,7 +338,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
}
toolbarDef.addShortCut(vcsAction);
//11.0.19及其之后加入回收站逻辑
if (!VcsHelper.getInstance().isLegacyMode()) {
if (VcsHelper.getInstance().checkV2FunctionSupport()) {
recycleAction = new RecycleAction();
toolbarDef.addShortCut(recycleAction);
}
@ -393,8 +394,11 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
private boolean isCurrentEditing(String path) {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
String editing = jt.getEditingFILE().getPath();
return ComparatorUtils.equals(editing, path);
if (JTemplate.isValid(jt)) {
String editing = jt.getEditingFILE().getPath();
return ComparatorUtils.equals(editing, path);
}
return false;
}
/**
@ -501,22 +505,25 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
public void actionPerformed(ActionEvent e) {
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
path = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, path);
boolean currentEditing = isCurrentEditing(path);
if (VcsHelper.getInstance().isLegacyMode()) {
boolean currentEditing = isCurrentEditing(path);
// 如果模板已经打开了,关掉,避免出现2个同名tab(1个是模板,1个是版本)
closeOpenedTemplate(path, currentEditing);
FileVersionsPanel fileVersionTablePanel = FileVersionsPanel.getInstance();
fileVersionTablePanel.showFileVersionsPane();
stateChange();
} else {
VcsNewPane panel = new VcsNewPane(path);
BasicDialog dialog = panel.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
checkTemplateSavedAndShowVcsNewPane(path, currentEditing);
}
}
private void showVcsNewPane(String path) {
VcsNewPane panel = new VcsNewPane(path);
panel.showDialog();
}
/**
* 版本管理可用状态的监控
*/
@ -570,6 +577,60 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
}
}
/**
* 如果指定模板已经打开
* <p>1.如果该模板已保存则正常打开新版本管理弹窗
* <p>2.如果该模板未保存触发保存逻辑
* <li>a.如果用户选择保存则保存并不关闭模板弹出新版本管理弹窗
* <li>b.如果用户选择不保存则关闭当前模板弹出新版本管理弹窗
* <li>c.如果用户选择取消, 则啥操作都不做
*
* @param path
* @param isCurrentEditing
*/
private void checkTemplateSavedAndShowVcsNewPane(String path, boolean isCurrentEditing) {
for (JTemplate jTemplate : HistoryTemplateListCache.getInstance().getHistoryList()) {
if (ComparatorUtils.equals(jTemplate.getEditingFILE().getPath(), path)) {
if (!jTemplate.isALLSaved()) {
MultiTemplateTabPane.getInstance().setIsCloseCurrent(isCurrentEditing);
MultiTemplateTabPane.getInstance().closeFormat(jTemplate);
confirmCloseAndShowVcsNewPane(jTemplate, path);
return;
}
}
}
showVcsNewPane(path);
}
private void confirmCloseAndShowVcsNewPane(JTemplate<?, ?> specifiedTemplate, String path) {
if (specifiedTemplate == null) {
return;
}
if (!specifiedTemplate.isALLSaved() && !DesignerMode.isVcsMode()) {
specifiedTemplate.stopEditing();
int returnVal = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Save") + " \"" + specifiedTemplate.getEditingFILE() + "\" ?",
Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (returnVal == JOptionPane.YES_OPTION) {
CallbackSaveWorker worker = specifiedTemplate.save();
worker.addSuccessCallback(() -> {
FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_Already_Saved", specifiedTemplate.getEditingFILE().getName()));
showVcsNewPane(path);
});
worker.start(specifiedTemplate.getRuntimeId());
} else if (returnVal == JOptionPane.NO_OPTION) {
closeTpl(specifiedTemplate);
showVcsNewPane(path);
}
} else {
showVcsNewPane(path);
}
}
private void closeTpl(JTemplate<?, ?> specifiedTemplate) {
HistoryTemplateListCache.getInstance().closeSelectedReport(specifiedTemplate);
MultiTemplateTabPane.getInstance().closeAndFreeLock(specifiedTemplate);
MultiTemplateTabPane.getInstance().activePrevTemplateAfterClose();
}
}

4
designer-base/src/main/java/com/fr/design/mainframe/vcs/RecycleAction.java

@ -4,7 +4,7 @@ import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.vcs.ui.RecyclePane;
import com.fr.design.mainframe.vcs.ui.RecycleSettingPane;
import java.awt.event.ActionEvent;
@ -24,7 +24,7 @@ public class RecycleAction extends UpdateAction {
@Override
public void actionPerformed(ActionEvent e) {
RecyclePane pane = new RecyclePane();
RecycleSettingPane pane = new RecycleSettingPane();
BasicDialog dialog = pane.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
}

37
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsExceptionUtils.java

@ -0,0 +1,37 @@
package com.fr.design.mainframe.vcs;
import com.fr.design.i18n.Toolkit;
import java.io.IOException;
import java.util.HashMap;
/**
* 版本管理异常处理工具类
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/24
*/
public class VcsExceptionUtils {
public static final HashMap<Class, String> EXCEPTION_MAP = new HashMap<Class, String>() {
{
put(IOException.class, Toolkit.i18nText("Fine-Design_Vcs_Exception_IO"));
put(UnsupportedOperationException.class, Toolkit.i18nText("Fine-Design_Vcs_Exception_Un_Support"));
}
};
/**
* 根据异常返回结果描述文案
*/
public static String createDetailByException(Exception e) {
for (Class key : EXCEPTION_MAP.keySet()) {
if (key.isAssignableFrom(e.getClass())) {
return EXCEPTION_MAP.get(key);
}
}
return Toolkit.i18nText("Fine-Design_Vcs_Exception_Unknown");
}
}

291
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsOperatorWorker.java

@ -0,0 +1,291 @@
package com.fr.design.mainframe.vcs;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.vcs.ui.VcsBatchProcessDetailPane;
import com.fr.design.mainframe.vcs.ui.VcsProgressDialog;
import com.fr.log.FineLoggerFactory;
import com.fr.report.entity.VcsEntity;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsOperator;
import javax.swing.SwingWorker;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
* 为版本中心回收站版本详情提供带进度条与结算面板的操作的worker
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/18
*/
public class VcsOperatorWorker {
private int count = 0;
private static final int FREQ = 5;
private String successStr;
private String title;
private String failedStr;
private String everyFailedStr;
private VcsProgressDialog dialog;
private static final String PREFIX = "(v.";
private static final String TAIL = ")";
public VcsOperatorWorker(String title, String dealingStr, String successStr, String failedStr, String everyFailedStr) {
this.title = title;
this.successStr = successStr;
this.failedStr = failedStr;
this.everyFailedStr = everyFailedStr;
dialog = new VcsProgressDialog(title, dealingStr);
}
public VcsOperatorWorker(String everyFailedStr) {
this.title = StringUtils.EMPTY;
this.successStr = StringUtils.EMPTY;
this.failedStr = StringUtils.EMPTY;
this.everyFailedStr = everyFailedStr;
}
/**
* 快速创建用于删除的worker
*
* @return
*/
public static VcsOperatorWorker createDeleteWorker() {
return new VcsOperatorWorker(
Toolkit.i18nText("Fine-Design_Vcs_Delete_Progress_Title"),
Toolkit.i18nText("Fine-Design_Vcs_Delete_Progress_Tips"),
Toolkit.i18nText("Fine-Design_Vcs_Delete_Progress_Success"),
"Fine-Design_Vcs_Delete_Progress_Failed",
Toolkit.i18nText("Fine-Design_Vcs_Delete_Every_Failed"));
}
/**
* 快速创建用于还原的worker
*
* @return
*/
public static VcsOperatorWorker createRestoreWorker() {
return new VcsOperatorWorker(
Toolkit.i18nText("Fine-Design_Vcs_Restore_Progress_Title"),
Toolkit.i18nText("Fine-Design_Vcs_Restore_Progress_Tips"),
Toolkit.i18nText("Fine-Design_Vcs_Restore_Progress_Success"),
"Fine-Design_Vcs_Restore_Progress_Failed",
Toolkit.i18nText("Fine-Design_Vcs_Restore_Every_Failed"));
}
/**
* 快速创建用于还原的worker
*
* @return
*/
public static VcsOperatorWorker createUpdateWorker() {
return new VcsOperatorWorker(Toolkit.i18nText("Fine-Design_Vcs_Update_Every_Failed"));
}
/**
* 批量还原
*
* @param vcsEntities 需要还原的版本
*/
public void batchRestore(List<VcsEntity> vcsEntities) {
List<String> failedList = new ArrayList<>();
startProcess(vcsEntities, failedList, (vcsEntity, operator) -> {
String fileName = vcsEntity.getFilename();
boolean result = true;
try {
operator.restoreVersion(fileName);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
result = false;
}
if (!result) {
failedList.add(fileName+PREFIX+vcsEntity.getVersion()+TAIL);
}
});
}
/**
* 批量删除
*
* @param vcsEntities 需要删除的版本
* @param all 是否需要删除所有版本
*/
public void batchDelete(List<VcsEntity> vcsEntities, boolean all) {
List<String> failedList = new ArrayList<>();
startProcess(vcsEntities, failedList, (vcsEntity, operator) -> {
String fileName = vcsEntity.getFilename();
boolean result = true;
try {
if (all) {
operator.deleteVersionForRecycle(fileName);
} else {
operator.deleteVersion(fileName, vcsEntity.getVersion());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
result = false;
}
if (!result) {
failedList.add(fileName+PREFIX+vcsEntity.getVersion()+TAIL);
}
});
}
/**
* 删除指定模板的全部历史版本
*
* @param entity VcsEntity
*/
public void doDelete(VcsEntity entity) {
String fileName = entity.getFilename();
start4Single(entity, (vcsEntity, operator) -> operator.deleteVersionForRecycle(fileName), fileName + everyFailedStr);
}
/**
* 删除指定模板的指定版本
*
* @param entity 版本
*/
public void deleteTargetVersion(VcsEntity entity) {
String fileName = entity.getFilename();
int version = entity.getVersion();
start4Single(entity, (vcsEntity, operator) -> {
operator.deleteVersion(fileName, version);
}, fileName + everyFailedStr);
}
/**
* 更新版本
*
* @param entity 版本
*/
public void updateEntityAnnotation(VcsEntity entity) {
start4Single(entity, (vcsEntity, operator) -> {
operator.updateVersion(entity);
}, everyFailedStr);
}
private void startProcess(List<VcsEntity> vcsEntities, List<String> failedList, VcsWorkerOperator workerOperator) {
try {
dialog.getProgressBar().setMaximum(vcsEntities.size());
start4Batch(vcsEntities, failedList, workerOperator);
dialog.showDialog();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 控制更新频率
*
* @return 是否需要更新进度
*/
private boolean needPublish() {
return (count > FREQ && count % FREQ == 0) || count < FREQ;
}
private void start4Single(VcsEntity entity, VcsWorkerOperator vcsWorkerOperator, String failedTip) {
new SwingWorker<Boolean, Void>() {
@Override
protected void done() {
try {
if (!get()) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), failedTip);
}
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
@Override
protected Boolean doInBackground() throws Exception {
try {
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
vcsWorkerOperator.process(entity, operator);
} catch (Exception e) {
return false;
}
return true;
}
}.execute();
}
private void start4Batch(List<VcsEntity> vcsEntities, List<String> failedList, VcsWorkerOperator workerOperator) {
new SwingWorker<Boolean, Integer>() {
@Override
protected Boolean doInBackground() throws Exception {
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
for (VcsEntity vcsEntity : vcsEntities) {
workerOperator.process(vcsEntity, operator);
count++;
if (needPublish()) {
publish(count);
}
}
return failedList.isEmpty();
}
@Override
protected void process(List<Integer> chunks) {
dialog.getProgressBar().setValue(chunks.get(chunks.size() - 1));
}
@Override
protected void done() {
dialog.closeDialog();
try {
showErrorDetailPane(get(), failedList, failedList.size(), vcsEntities.size() - failedList.size());
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}.execute();
}
private void showErrorDetailPane(boolean result, List<String> failedList, int failed, int success) {
if (result) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), successStr);
} else {
VcsBatchProcessDetailPane pane = new VcsBatchProcessDetailPane(
DesignerContext.getDesignerFrame(),
title,
Toolkit.i18nText(failedStr, failed, success)
);
for (String msg : failedList) {
pane.updateDetailArea(msg + everyFailedStr);
}
pane.show();
}
}
/**
* Vcs面板操作处理接口
*
*/
private interface VcsWorkerOperator {
/**
* 处理
*
* @param vcsEntity 版本
* @param operator 操作类
*/
void process(VcsEntity vcsEntity, VcsOperator operator) throws Exception;
}
}

49
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsRecycleSettingHelper.java

@ -0,0 +1,49 @@
package com.fr.design.mainframe.vcs;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerAdaptor;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsConfig;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanOperator;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanService;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoRecycleSchedule;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 版本管理界面配置回收事件的处理类
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/21
*/
public class VcsRecycleSettingHelper {
private static ExecutorService executorService = Executors.newSingleThreadExecutor(new NamedThreadFactory("VcsRecycle"));
/**
* 更新任务
*
* @param day
*/
public static void updateJob(int day) {
executorService.execute(new Runnable() {
@Override
public void run() {
Configurations.update(new WorkerAdaptor(VcsConfig.class) {
@Override
public void run() {
VcsConfig.getInstance().setV2CleanRecycleInterval(day);
}
});
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).addOrUpdateVcsAutoCleanJob(
VcsAutoCleanService.VCS_AUTO_CLEAN_RECYCLE_JOB_NAME,
1,
VcsAutoRecycleSchedule.class);
}
});
}
}

162
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsService.java

@ -1,162 +0,0 @@
package com.fr.design.mainframe.vcs;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.log.FineLoggerFactory;
import com.fr.report.entity.VcsEntity;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsOperator;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 版本管理常用操作
* <p>便于版本管理面板快捷实现版本管理相关操作
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/10
*/
public class VcsService {
private static final String SERVICE = "VcsService";
private static final VcsService INSTANCE = new VcsService();
private static final ExecutorService executorService = Executors.newFixedThreadPool(5, new NamedThreadFactory(SERVICE));
/**
* 获取单例
*
* @return
*/
public static VcsService getInstance() {
return INSTANCE;
}
private VcsService() {
}
/**
* 回收模板
*
* @param filename
*/
public void doRecycle(String filename) {
try {
WorkContext.getCurrent().get(VcsOperator.class).recycleVersion(VcsHelper.getInstance().getCurrentUsername(), filename);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 从回收站还原版本
*
* @param vcsEntities
*/
public void doRestore(List<VcsEntity> vcsEntities) {
try {
executorService.execute(new Runnable() {
@Override
public void run() {
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
for (VcsEntity vcsEntity : vcsEntities) {
String fileName = vcsEntity.getFilename();
operator.restoreVersion(fileName);
}
}
});
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 删除对应列表中所有模板的指定的历史版本
*
* @param vcsEntities
*/
public void doDelete(List<VcsEntity> vcsEntities, boolean all) {
try {
executorService.execute(new Runnable() {
@Override
public void run() {
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
for (VcsEntity vcsEntity : vcsEntities) {
String fileName = vcsEntity.getFilename();
if (all) {
operator.deleteVersionForRecycle(fileName);
} else {
operator.deleteVersion(fileName, vcsEntity.getVersion());
}
}
}
});
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 删除指定模板的全部历史版本
*
* @param entity VcsEntity
*/
public void deleteEntity(VcsEntity entity) {
try {
executorService.execute(new Runnable() {
@Override
public void run() {
VcsOperator vcsOperator = WorkContext.getCurrent().get(VcsOperator.class);
String fileName = entity.getFilename();
vcsOperator.deleteVersionForRecycle(fileName);
}
});
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 删除指定模板的指定版本
*
* @param fileName 文件名
* @param version 版本号
*/
public void deleteEntity(String fileName, int version) {
try {
executorService.execute(new Runnable() {
@Override
public void run() {
VcsOperator vcsOperator = WorkContext.getCurrent().get(VcsOperator.class);
vcsOperator.deleteVersion(fileName, version);
}
});
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 更新版本
*
* @param entity 版本
*/
public void updateEntityAnnotation(VcsEntity entity) {
try {
executorService.execute(new Runnable() {
@Override
public void run() {
VcsOperator vcsOperator = WorkContext.getCurrent().get(VcsOperator.class);
vcsOperator.updateVersion(entity);
}
});
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}

9
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsTableEntity.java

@ -1,6 +1,7 @@
package com.fr.design.mainframe.vcs;
import com.fr.report.entity.VcsEntity;
import com.fr.stable.StringUtils;
/**
* 包装VcsEntity的用于表格展示与处理的类
@ -16,7 +17,7 @@ public class VcsTableEntity implements TableEntity{
private static final String MB = "MB";
private static final String VERSION = "V.";
private static final double MB_SIZE = 1024.0;
private static final double MB_SIZE = 1024.0 * 1024;
private VcsEntity entity;
@ -39,7 +40,11 @@ public class VcsTableEntity implements TableEntity{
* @return 版本大小
*/
public String getSize() {
return String.format("%.2f",entity.getSize()/MB_SIZE) + MB;
double size = entity.getSize()/MB_SIZE;
if (size == 0) {
return StringUtils.EMPTY;
}
return String.format("%.3f", size) + MB;
}
/**

33
designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java

@ -15,6 +15,7 @@ import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.mainframe.vcs.ui.FileVersionTable;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.ListenerAdaptor;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
@ -24,6 +25,8 @@ import com.fr.report.entity.VcsEntity;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent;
import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.workspace.server.vcs.filesystem.VcsFileSystem;
import com.fr.workspace.server.vcs.git.config.GcConfig;
@ -66,6 +69,8 @@ public class VcsHelper implements JTemplateActionListener {
private volatile boolean legacyMode;
private volatile boolean root;
public static VcsHelper getInstance() {
return INSTANCE;
}
@ -74,7 +79,14 @@ public class VcsHelper implements JTemplateActionListener {
VcsOperator op = WorkContext.getCurrent().get(VcsOperator.class);
// 开了设计器启动页面时一开始取不到VcsOperator,通过下面的切换环境事件再取,这边判断下
if (op != null) {
legacyMode = op.isLegacyMode();
try {
legacyMode = op.isLegacyMode();
root = WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot();
} catch (Exception e) {
legacyMode = true;
root = false;
FineLoggerFactory.getLogger().error("[VcsHelper] init first failed ", e.getMessage());
}
}
EventDispatcher.listen(ConfigEvent.READY, new ListenerAdaptor() {
@Override
@ -89,6 +101,18 @@ public class VcsHelper implements JTemplateActionListener {
}
}
});
EventDispatcher.listen(WorkspaceEvent.AfterSwitch, new Listener<Workspace>() {
@Override
public void on(Event event, Workspace param) {
try {
root = WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot() ;
} catch (Exception e) {
root = false;
FineLoggerFactory.getLogger().error("[VcsHelper] get root failed", e.getMessage());
}
}
});
}
/**
@ -327,7 +351,7 @@ public class VcsHelper implements JTemplateActionListener {
private void autoSave(JTemplate jt, String currentUsername, String fileName, int nowVersion, boolean replace, VcsOperator operator) {
try {
if (JTemplate.isValid(jt)) {
if (JTemplate.isValid(jt) && !jt.isALLSaved()) {
operator.autoSave(currentUsername, fileName, StringUtils.EMPTY, nowVersion, jt.exportData(), replace);
}
} catch (Exception e) {
@ -347,7 +371,8 @@ public class VcsHelper implements JTemplateActionListener {
public void templateSaved(JTemplate<?, ?> jt) {
if (needInit()
&& DesignerEnvManager.getEnvManager().getVcsConfigManager().isVcsEnable()
&& !WorkContext.getCurrent().isCluster()) {
// 如果是集群,在新版本下才生效
&& (!WorkContext.getCurrent().isCluster() || !VcsHelper.getInstance().isLegacyMode())) {
fireVcs(jt);
}
}
@ -370,7 +395,7 @@ public class VcsHelper implements JTemplateActionListener {
* @return 支持返回true
*/
public boolean checkV2FunctionSupport() {
return !VcsHelper.getInstance().isLegacyMode() && (WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot());
return !VcsHelper.getInstance().isLegacyMode() && root;
}
/**

32
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/AbstractSupportSelectTablePane.java

@ -1,5 +1,6 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.data.tabledata.tabledatapane.loading.TipsPane;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.icheckbox.UICheckBox;
@ -219,6 +220,17 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
//更新表头的勾选框状态
HeaderRenderer renderer = (HeaderRenderer) table.getTableHeader().getDefaultRenderer();
renderer.refreshHeader(table, selectCount >= table.getRowCount());
changeExtraComponentStatus();
}
/**
* 更新额外组件的状态
*/
protected void changeExtraComponentStatus() {
}
public int getSelectCount() {
return selectCount;
}
@ -242,6 +254,7 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
public HeaderRenderer(JTable table) {
this.tableHeader = table.getTableHeader();
tableHeader.setCursor(new Cursor(Cursor.HAND_CURSOR));
selectBox = new UICheckBox();
selectBox.setSelected(false);
tableHeader.addMouseListener(new MouseAdapter() {
@ -254,6 +267,7 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
selectBox.setSelected(value);
selectAllOrNull(value);
selectCount = value ? table.getRowCount() : 0;
changeExtraComponentStatus();
tableHeader.repaint();
model.fireTableDataChanged();
}
@ -290,8 +304,12 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
tableHeader = table.getTableHeader();
tableHeader.setReorderingAllowed(false);
String valueStr = (String) value;
JLabel label = new JLabel(valueStr);
label.setHorizontalAlignment(SwingConstants.LEFT);
UILabel label = new UILabel(valueStr);
if (needIcon4Head(column)) {
label.setIcon(IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_sort"));
label.setHorizontalTextPosition(JLabel.LEFT);
label.setHorizontalAlignment(SwingConstants.LEFT);
}
selectBox.setHorizontalAlignment(SwingConstants.CENTER);
selectBox.setBorderPainted(true);
JComponent component = (column == 0) ? selectBox : label;
@ -320,6 +338,7 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
setColumnClass(classes);
this.setDefaultEditor(Boolean.class, new BooleanEditor());
this.setDefaultRenderer(Boolean.class, new BooleanRenderer());
this.setDefaultRenderer(UILabel.class, new ToolTipTableCellRenderer());
}
@Override
@ -375,5 +394,14 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
}
/**
* 表头的某列是否需要icon
*
* @param col
* @return
*/
protected boolean needIcon4Head(int col) {
return col != 0;
}
}

120
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecyclePane.java

@ -1,11 +1,13 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.vcs.VcsService;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.vcs.VcsOperatorWorker;
import com.fr.design.mainframe.vcs.TableEntity;
import com.fr.design.mainframe.vcs.TableValueOperator;
import com.fr.design.mainframe.vcs.VcsTableEntity;
@ -37,8 +39,10 @@ import static com.fr.design.i18n.Toolkit.i18nText;
*/
public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity> {
public static final Icon ICON_SEARCH = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_recycle_search");
public static final Icon ICON_REFRESH = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_recycle_restore");
public static final Icon ICON_DELETE = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_recycle_delete");
public static final Icon ICON_REFRESH = IconUtils.readSVGIcon("/com/fr/design/standard/vcslist/vcs_recycle_restore", IconUtils.ICON_TYPE_NORMAL);
public static final Icon ICON_REFRESH_DISABLE = IconUtils.readSVGIcon("/com/fr/design/standard/vcslist/vcs_recycle_restore", IconUtils.ICON_TYPE_DISABLED);
public static final Icon ICON_DELETE = IconUtils.readSVGIcon("/com/fr/design/standard/vcslist/vcs_recycle_delete", IconUtils.ICON_TYPE_NORMAL);
public static final Icon ICON_DELETE_DISABLE = IconUtils.readSVGIcon("/com/fr/design/standard/vcslist/vcs_recycle_delete", IconUtils.ICON_TYPE_DISABLED);
protected UITextField searchTextField;
@ -47,6 +51,10 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
protected UILabel restoreLabel;
private static final int COLUMNS_COUNT = 15;
private BasicDialog dialog;
private BasicDialog parentDialog;
private List<VcsTableEntity> tableEntities;
public RecyclePane() {
super(i18nText("Fine-Design_Vcs_Recycle"), (o, columnIndex) -> {
@ -71,7 +79,7 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
Toolkit.i18nText("Fine-Design_Vcs_Recycle_Size"),
Toolkit.i18nText("Fine-Design_Vcs_Delete_Time"),
Toolkit.i18nText("Fine-Design_Vcs_Time")
}, true);
}, false);
}
public RecyclePane(String title, TableValueOperator<VcsTableEntity> operators, boolean needBorder) {
@ -86,6 +94,7 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
for (VcsEntity entity : entityList) {
tableEntities.add(new VcsTableEntity(entity));
}
updateTableList(tableEntities);
return tableEntities;
}
@ -108,17 +117,33 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
if (isNeedRestore()) {
restoreLabel = new UILabel(ICON_REFRESH);
restoreLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
restoreLabel.setDisabledIcon(ICON_REFRESH_DISABLE);
restoreLabel.setEnabled(false);
rightPane.add(restoreLabel);
}
if (isNeedDelete()) {
deleteLabel = new UILabel(ICON_DELETE);
deleteLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
deleteLabel.setDisabledIcon(ICON_DELETE_DISABLE);
deleteLabel.setEnabled(false);
rightPane.add(deleteLabel);
}
tableTopPane.add(leftPane, BorderLayout.EAST);
tableTopPane.add(rightPane, BorderLayout.WEST);
}
@Override
protected void changeExtraComponentStatus() {
boolean canUseLabel = getSelectCount() > 0;
if (restoreLabel != null) {
restoreLabel.setEnabled(canUseLabel);
}
if (deleteLabel != null) {
deleteLabel.setEnabled(canUseLabel);
}
}
@Override
protected void initTopPaneListener() {
initSearchTextFiledListener();
@ -128,13 +153,14 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
private void initDeleteLabelListener() {
if (isNeedDelete()) {
deleteLabel.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Delete"));
deleteLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
fireListener(new VcsResponseListener() {
@Override
public void doAfterChooseYes(List<VcsEntity> selectList) {
VcsService.getInstance().doDelete(selectList, isNeedDeleteAllVersion());
VcsOperatorWorker.createDeleteWorker().batchDelete(selectList, isNeedDeleteAllVersion());
}
}, true);
}
@ -144,13 +170,14 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
private void initRestoreListener() {
if (isNeedRestore()) {
restoreLabel.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Restore"));
restoreLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
fireListener(new VcsResponseListener() {
@Override
public void doAfterChooseYes(List<VcsEntity> selectList) {
VcsService.getInstance().doRestore(selectList);
VcsOperatorWorker.createRestoreWorker().batchRestore(selectList);
}
}, false);
}
@ -164,8 +191,7 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
@Override
public void actionPerformed(ActionEvent e) {
String str = searchTextField.getText();
List<VcsTableEntity> entityList = model.getList();
model.setList(entityList.stream().filter(entity -> entity.getEntity().getFilename().contains(str)).collect(Collectors.toList()));
model.setList(tableEntities.stream().filter(entity -> entity.getEntity().getFilename().contains(str)).collect(Collectors.toList()));
model.fireTableDataChanged();
}
});
@ -173,6 +199,7 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
}
private void fireListener(VcsResponseListener listener, boolean isDelete) {
List<VcsEntity> selectList = model.getList().stream().filter(TableEntity::isSelect).map(VcsTableEntity::getEntity).collect(Collectors.toList());
if (selectList.size() > 0) {
@ -183,7 +210,8 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (selVal == JOptionPane.YES_OPTION) {
model.setList(model.getList().stream().filter(tableEntity -> !tableEntity.isSelect()).collect(Collectors.toList()));
tableEntities = model.getList().stream().filter(tableEntity -> !tableEntity.isSelect()).collect(Collectors.toList());
model.setList(tableEntities);
model.fireTableDataChanged();
listener.doAfterChooseYes(selectList);
}
@ -191,6 +219,61 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
}
/**
* 显示弹窗
*
*/
public void showDialog() {
dialog = this.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
}
/**
* 依据父弹窗显示弹窗
*
* @param parent 父弹窗
*/
public void showDialog(BasicDialog parent) {
this.parentDialog = parent;
dialog = this.showWindow(parent, false);
initDialogListener(dialog);
dialog.setVisible(true);
}
protected void initDialogListener(BasicDialog dialog) {
}
/**
* 关闭弹窗,如果有父弹窗,则一起关闭,如果有属性配置的弹窗面板要保存再关闭
*
*/
public void saveSettingAndCloseDialog() {
if (dialog != null) {
dialog.doOK();
dialog.dispose();
}
if (parentDialog != null) {
parentDialog.doOK();
parentDialog.dispose();
}
}
public BasicDialog getDialog() {
return dialog;
}
public void setDialog(BasicDialog dialog) {
this.dialog = dialog;
}
public BasicDialog getParentDialog() {
return parentDialog;
}
public void setParentDialog(BasicDialog parentDialog) {
this.parentDialog = parentDialog;
}
/**
* 删除范围
*
@ -250,6 +333,25 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
return true;
}
/**
* 更新数据列表
*
* @param entities
*/
public void updateTableList(List<VcsTableEntity> entities) {
tableEntities = entities;
}
/**
* 移除指定元素
*
* @param entity
*/
public void removeTarget(VcsTableEntity entity) {
tableEntities.remove(entity);
}
/**
* 版本管理按钮事件响应
*/

103
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecycleSettingPane.java

@ -0,0 +1,103 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.frpane.UITabbedPane;
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.ispinner.UISpinner;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.vcs.VcsRecycleSettingHelper;
import com.fr.workspace.server.vcs.VcsConfig;
import javax.swing.JPanel;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 回收站配置面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/21
*/
public class RecycleSettingPane extends BasicPane {
private static final int MIN_VALUE = 1;
private static final int MAX_VALUE = 999;
private static final int STEP = 1;
private static final int DEFAULT_VALUE = 30;
private UISpinner spinner;
private UIButton button;
public RecycleSettingPane() {
init();
}
private void init() {
this.setLayout(new BorderLayout());
UITabbedPane tabbedPane = new UITabbedPane();
//回收站内容
JPanel recyclePane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
UIScrollPane recycleScrollPane = patchScroll(recyclePane);
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Vcs_Recycle_Content"), recycleScrollPane);
recyclePane.add(new RecyclePane());
//通用设置
JPanel settingPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
UIScrollPane settingScrollPane = patchScroll(settingPane);
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Carton_General_Settings"), settingScrollPane);
settingPane.add(createSchedulePane());
this.add(tabbedPane, BorderLayout.CENTER);
}
private JPanel createSchedulePane() {
JPanel schedulePane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 0);
JPanel spinnerPane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane_First0();
JPanel buttonPane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane_First0();
spinnerPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Recycle_Schedule")));
spinner = new UISpinner(MIN_VALUE, MAX_VALUE, STEP, DEFAULT_VALUE);
spinner.setValue(VcsConfig.getInstance().getV2CleanRecycleInterval());
spinnerPane.add(spinner);
spinnerPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Recycle_Schedule_Day")));
schedulePane.add(spinnerPane);
button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Save"));
initButtonListener();
buttonPane.add(button);
schedulePane.add(buttonPane);
return schedulePane;
}
private void initButtonListener() {
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
VcsRecycleSettingHelper.updateJob((int) spinner.getValue());
}
});
}
private UIScrollPane patchScroll(JPanel generalPane) {
UIScrollPane generalPanelWithScroll = new UIScrollPane(generalPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
generalPanelWithScroll.setBorder(new EmptyBorder(0, 0, 0, 0));
return generalPanelWithScroll;
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Vcs_Recycle");
}
}

32
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/ToolTipTableCellRenderer.java

@ -0,0 +1,32 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.general.GeneralUtils;
import com.fr.stable.StringUtils;
import javax.swing.JTable;
import javax.swing.JLabel;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
/**
* 带ToolTip的UILabel的表格渲染类
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/21
*/
public class ToolTipTableCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if(component instanceof JLabel) {
String toolTipText = GeneralUtils.objectToString(value);
if (StringUtils.isNotEmpty(toolTipText)) {
((JLabel) component).setToolTipText(toolTipText);
}
}
return component;
}
}

59
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/UIPositiveIntEditor.java

@ -0,0 +1,59 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.editor.editor.IntegerEditor;
import com.fr.design.gui.itextfield.UIIntNumberField;
import com.fr.design.gui.itextfield.UINumberField;
import com.fr.stable.StringUtils;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
/**
* 正整数输入框
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/25
*/
public class UIPositiveIntEditor extends IntegerEditor {
private static final int DEFAULT_COLUMNS = 4;
private static final int MIN = 1;
private static final int MAX = 99999;
private static final int DEFAULT_VALUE = 60;
public UIPositiveIntEditor(Integer value) {
super(value);
numberField.setMaxValue(MAX);
numberField.setMinValue(MIN);
initNumberFieldListener();
}
public UIPositiveIntEditor(Integer value, Integer min, Integer max) {
super(value);
numberField.setMaxValue(max);
numberField.setMinValue(min);
initNumberFieldListener();
}
private void initNumberFieldListener() {
numberField.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
if (StringUtils.isEmpty(numberField.getTextValue())) {
numberField.setValue(DEFAULT_VALUE);
}
}
});
}
@Override
protected UINumberField createNumberField() {
UIIntNumberField field = new UIIntNumberField();
field.setColumns(DEFAULT_COLUMNS);
return field;
}
}

39
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/UIPositiveIntSpinner.java

@ -0,0 +1,39 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.gui.itextfield.UIIntNumberField;
import com.fr.design.gui.itextfield.UINumberField;
/**
* 只允许输入正整数的Spinner
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/25
*/
public class UIPositiveIntSpinner extends UISpinner {
private static final int DEFAULT_COLUMNS = 5;
public UIPositiveIntSpinner() {
}
public UIPositiveIntSpinner(double minValue, double maxValue, double dierta) {
super(minValue, maxValue, dierta);
}
public UIPositiveIntSpinner(double minValue, double maxValue, double dierta, double defaultValue) {
super(minValue, maxValue, dierta, defaultValue);
}
public UIPositiveIntSpinner(double minValue, double maxValue, double dierta, double defaultValue, boolean fillNegativeNumber) {
super(minValue, maxValue, dierta, defaultValue, fillNegativeNumber);
}
@Override
protected UINumberField initNumberField() {
UIIntNumberField field = new UIIntNumberField();
field.setColumns(DEFAULT_COLUMNS);
return field;
}
}

156
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsBatchProcessDetailPane.java

@ -0,0 +1,156 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* 处理结果详细面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/19
*/
public class VcsBatchProcessDetailPane {
private UILabel message = new UILabel();
private UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK"));
private UILabel uiLabel = new UILabel();
private UILabel directUiLabel = new UILabel();
private UILabel detailLabel = new UILabel();
private JPanel upPane;
private JPanel midPane;
private JPanel downPane;
private JPanel hiddenPanel;
private JTextArea jta;
private JDialog dialog;
public static final Dimension DEFAULT = new Dimension(380, 150);
public static final Dimension DEFAULT_PRO = new Dimension(380, 270);
public VcsBatchProcessDetailPane(Frame parent, String title, String msg) {
init(parent, title, msg);
}
private void init(Frame parent, String title, String msg) {
message.setBorder(BorderFactory.createEmptyBorder(8, 5, 0, 0));
message.setText(msg);
dialog = new JDialog(parent, title, true);
dialog.setSize(DEFAULT);
JPanel jp = new JPanel();
initUpPane();
initDownPane();
initMidPane();
initHiddenPanel();
initListener();
jp.setLayout(new BoxLayout(jp, BoxLayout.Y_AXIS));
jp.add(upPane);
jp.add(midPane);
jp.add(hiddenPanel);
jp.add(downPane);
hiddenPanel.setVisible(false);
dialog.add(jp);
dialog.setResizable(false);
dialog.setLocationRelativeTo(SwingUtilities.getWindowAncestor(parent));
}
private void initDownPane() {
downPane = new JPanel();
downPane.setLayout(new FlowLayout(FlowLayout.RIGHT, 15, 9));
downPane.add(cancelButton);
}
private void initUpPane() {
upPane = new JPanel();
uiLabel = new UILabel(UIManager.getIcon("OptionPane.errorIcon"));
upPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10));
upPane.add(uiLabel);
upPane.add(message);
}
private void initMidPane() {
midPane = new JPanel();
midPane.add(directUiLabel);
midPane.add(detailLabel);
midPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0));
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail"));
detailLabel.setForeground(Color.BLUE);
detailLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right"));
}
private void initHiddenPanel() {
hiddenPanel = new JPanel();
hiddenPanel.setLayout(new BorderLayout(2, 0));
hiddenPanel.add(new JPanel(), BorderLayout.WEST);
hiddenPanel.add(new JPanel(), BorderLayout.EAST);
JPanel borderPanel = new JPanel();
borderPanel.setLayout(new BorderLayout());
jta = new JTextArea();
JScrollPane jsp = new JScrollPane(jta);
jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jta.setEditable(false);
borderPanel.add(jsp, BorderLayout.CENTER);
hiddenPanel.add(borderPanel);
}
/**
* 补充更详细的报错信息
*
* @param message 信息
*/
public void updateDetailArea(String message) {
jta.append(message + "\n");
}
private void initListener() {
detailLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (hiddenPanel.isVisible()) {
hiddenPanel.setVisible(false);
dialog.setSize(DEFAULT);
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail"));
directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right"));
} else {
dialog.setSize(DEFAULT_PRO);
hiddenPanel.setVisible(true);
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Hide_Detail"));
directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down"));
}
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hiddenPanel.removeAll();
dialog.dispose();
}
});
}
/**
* 显示面板
*/
public void show() {
dialog.setVisible(true);
}
}

35
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCellEditor.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.vcs.ui;
import javax.swing.AbstractCellEditor;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import java.awt.*;
import static com.fr.design.mainframe.vcs.ui.AbstractSupportSelectTablePane.DEFAULT_SELECT_TABLE_ROW_COLOR;
/**
* Vcs的表格Editor
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/20
*/
public class VcsCellEditor extends AbstractCellEditor implements TableCellEditor {
private final VcsOperatorPane vcsPanel;
public VcsCellEditor(VcsOperatorPane vcsPanel) {
this.vcsPanel = vcsPanel;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
vcsPanel.setBackground(isSelected ? DEFAULT_SELECT_TABLE_ROW_COLOR : Color.WHITE);
return vcsPanel;
}
@Override
public Object getCellEditorValue() {
return vcsPanel;
}
}

29
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCellRender.java

@ -0,0 +1,29 @@
package com.fr.design.mainframe.vcs.ui;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import static com.fr.design.mainframe.vcs.ui.AbstractSupportSelectTablePane.DEFAULT_SELECT_TABLE_ROW_COLOR;
/**
* Vcs的表格Render
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/20
*/
public class VcsCellRender implements TableCellRenderer {
private final VcsOperatorPane vcsPanel;
public VcsCellRender(VcsOperatorPane vcsPanel) {
this.vcsPanel = vcsPanel;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
vcsPanel.setBackground(isSelected ? DEFAULT_SELECT_TABLE_ROW_COLOR : Color.WHITE);
return vcsPanel;
}
}

38
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCenterPane.java

@ -2,11 +2,12 @@ package com.fr.design.mainframe.vcs.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.vcs.VcsService;
import com.fr.design.mainframe.vcs.VcsOperatorWorker;
import com.fr.design.mainframe.vcs.VcsTableEntity;
import com.fr.file.FileNodeFILE;
@ -83,8 +84,11 @@ public class VcsCenterPane extends VcsNewPane {
@Override
public VcsOperatorPane createOperatorPane() {
manager = new UILabel(MANAGER_ICON);
manager.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Manager"));
open = new UILabel(OPEN_ICON);
open.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Open"));
delete = new UILabel(DELETE_ICON);
delete.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Delete"));
initManagerListener();
initOpenListener();
initDeleteListener();
@ -111,7 +115,10 @@ public class VcsCenterPane extends VcsNewPane {
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (selVal == JOptionPane.YES_OPTION) {
VcsService.getInstance().deleteEntity(entity);
VcsOperatorWorker.createDeleteWorker().doDelete(entity);
removeTarget((VcsTableEntity) o);
model.getList().remove(o);
model.fireTableDataChanged();
}
DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(getTemplateTruePath(fileName), false)));
}
@ -119,6 +126,12 @@ public class VcsCenterPane extends VcsNewPane {
});
}
@Override
protected boolean needIcon4Head(int col) {
return col != 0 && col != OPERATOR_COL;
}
private void initOpenListener() {
open.addMouseListener(new MouseAdapter() {
@Override
@ -127,6 +140,7 @@ public class VcsCenterPane extends VcsNewPane {
Object o = table.getValueAt(table.getEditingRow(), table.getEditingColumn());
if (o instanceof VcsTableEntity) {
VcsEntity entity = ((VcsTableEntity) o).getEntity();
saveSettingAndCloseDialog();
DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(getTemplateTruePath(entity.getFilename()), false)));
}
}
@ -147,8 +161,7 @@ public class VcsCenterPane extends VcsNewPane {
return entity.getFilename()+Toolkit.i18nText("Fine-Design_Vcs_Version_Tips");
}
};
BasicDialog dialog = pane.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
pane.showDialog(getDialog());
}
}
});
@ -161,9 +174,21 @@ public class VcsCenterPane extends VcsNewPane {
for (VcsEntity entity : entities) {
tableEntities.add(new VcsTableEntity(entity));
}
updateTableList(tableEntities);
return tableEntities;
}
@Override
protected void initDialogListener(BasicDialog dialog) {
dialog.addDialogActionListener(new DialogActionAdapter() {
@Override
public void doOk() {
getParentDialog().doOK();
getParentDialog().dispose();
}
});
}
@Override
protected String title4PopupWindow() {
return TITLE;
@ -194,4 +219,9 @@ public class VcsCenterPane extends VcsNewPane {
protected boolean isNeedSearch() {
return true;
}
@Override
protected boolean isNeedDeleteAllVersion() {
return true;
}
}

95
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsMovePanel.java

@ -5,6 +5,7 @@ import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.BasicDialog;
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.ibutton.UIRadioButton;
import com.fr.design.gui.ilable.UILabel;
@ -14,8 +15,11 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.vcs.VcsExceptionUtils;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.ThemeUtils;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.general.FRFont;
import com.fr.log.FineLoggerFactory;
@ -25,6 +29,7 @@ import com.fr.workspace.server.vcs.v2.move.VcsMoveStrategy;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
@ -37,6 +42,9 @@ import java.awt.event.MouseEvent;
import java.util.List;
import java.util.concurrent.ExecutionException;
import static javax.swing.JOptionPane.YES_NO_CANCEL_OPTION;
import static javax.swing.JOptionPane.YES_OPTION;
/**
* 迁移面板
@ -75,6 +83,8 @@ public class VcsMovePanel extends BasicPane {
public static final String FAILED = "FAILED";
public static boolean moving = false;
private BasicDialog parentDialog;
private UILabel vcsUpdateExistLabel = new UILabel();
private UILabel vcsUpdateFireLabel = new UILabel();
@ -103,7 +113,7 @@ public class VcsMovePanel extends BasicPane {
//全部放弃
private UIRadioButton moveNothingButton;
private UISpinner spinner;
private UIPositiveIntSpinner spinner;
private MoveCallBack callBack;
@ -112,11 +122,12 @@ public class VcsMovePanel extends BasicPane {
private boolean visible = false;
public VcsMovePanel(CardLayout cardLayout, JPanel parentPane, MoveCallBack callBack) {
public VcsMovePanel(CardLayout cardLayout, JPanel parentPane, MoveCallBack callBack, BasicDialog parentDialog) {
this.parentCard = cardLayout;
this.parentPane = parentPane;
this.callBack = callBack;
this.setLayout(new BorderLayout());
this.parentDialog = parentDialog;
updatePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane();
updatePane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0));
//初始化顶部的面板
@ -228,7 +239,7 @@ public class VcsMovePanel extends BasicPane {
moveAllPane.add(moveAllButton);
moveDefaultPanel.add(moveDefaultButton);
moveDefaultPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Default_Text_Left")));
spinner = new UISpinner(MIN_VALUE, MAX_VALUE, STEP, DEFAULT_VALUE);
spinner = new UIPositiveIntSpinner(MIN_VALUE, MAX_VALUE, STEP, DEFAULT_VALUE);
moveDefaultPanel.add(spinner);
moveDefaultPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Default_Text_Right")));
moveNothingPane.add(moveNothingButton);
@ -238,7 +249,9 @@ public class VcsMovePanel extends BasicPane {
}
private void initVcsLabel(JPanel parent) {
parent.removeAll();
if (!VcsHelper.getInstance().isLegacyMode()) {
parent.setBackground(ThemeUtils.BACK_COLOR);
centerButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Center"));
parent.add(centerButton);
initVcsCenterListener();
@ -259,9 +272,7 @@ public class VcsMovePanel extends BasicPane {
@Override
public void actionPerformed(ActionEvent e) {
VcsCenterPane vcsCenterPane = new VcsCenterPane();
BasicDialog dialog = vcsCenterPane.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
vcsCenterPane.showDialog(parentDialog);
}
});
}
@ -273,18 +284,7 @@ public class VcsMovePanel extends BasicPane {
BasicDialog dlg = choosePane.showMediumWindow(SwingUtilities.getWindowAncestor(VcsMovePanel.this), new DialogActionAdapter() {
@Override
public void doOk() {
//进度条面板
initProcessPane();
VcsMovePanel.this.getParentCard().next(getParentPane());
VcsMoveStrategy strategy;
if (moveDefaultButton.isSelected()) {
strategy = VcsMoveStrategy.createNumStrategy((int) spinner.getValue());
} else if (moveNothingButton.isSelected()) {
strategy = VcsMoveStrategy.ALL_GIVE_UP;
} else {
strategy = VcsMoveStrategy.ALL_RETAIN;
}
new MoveWorker(strategy).execute();
createConfirmPane();
}
});
dlg.setVisible(true);
@ -292,6 +292,42 @@ public class VcsMovePanel extends BasicPane {
});
}
private void createConfirmPane() {
VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP);
layout.setAlignLeft(true);
JPanel panel = new JPanel();
panel.setLayout(layout);
UILabel titleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Tip_Title"));
UILabel firstLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Tip_First"));
UILabel secondLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Tip_Second"));
titleLabel.setForeground(TIP_COLOR);
firstLabel.setForeground(TIP_COLOR);
secondLabel.setForeground(TIP_COLOR);
panel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Right_Now")));
panel.add(titleLabel);
panel.add(firstLabel);
panel.add(secondLabel);
int value = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), panel, Toolkit.i18nText("Fine-Design_Vcs_Move_Title"), JOptionPane.YES_NO_OPTION);
processMove(value);
}
private void processMove(int value) {
if (value == YES_OPTION) {
//进度条面板
initProcessPane();
VcsMovePanel.this.getParentCard().next(getParentPane());
VcsMoveStrategy strategy;
if (moveDefaultButton.isSelected()) {
strategy = VcsMoveStrategy.createStrategy((int) spinner.getValue());
} else if (moveNothingButton.isSelected()) {
strategy = VcsMoveStrategy.createStrategy(0);
} else {
strategy = VcsMoveStrategy.createStrategy(Integer.MAX_VALUE);
}
new MoveWorker(strategy).execute();
}
}
private void initSuccessPane() {
JPanel successPane = new JPanel();
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
@ -324,15 +360,19 @@ public class VcsMovePanel extends BasicPane {
private void doAfterMove() {
visible = !VcsHelper.getInstance().isLegacyMode();
if (visible) {
updatePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane();
updatePane.add(new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Center")));
}
updatePane.setVisible(!visible);
initVcsLabel(updatePane);
updatePane.setVisible(visible);
callBack.doCallBack(visible);
parentCard.show(parentPane, SETTING);
}
public BasicDialog getParentDialog() {
return parentDialog;
}
public void setParentDialog(BasicDialog parentDialog) {
this.parentDialog = parentDialog;
}
@Override
protected String title4PopupWindow() {
@ -347,7 +387,7 @@ public class VcsMovePanel extends BasicPane {
return parentPane;
}
private void initFailedPane() {
private void initFailedPane(String detail) {
JPanel failedPane = new JPanel();
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
failedButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Go"));
@ -355,7 +395,7 @@ public class VcsMovePanel extends BasicPane {
failedIconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/move_failed.svg"));
failedLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed"));
failedLabel.setFont(FONT);
failedTipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Tip"));
failedTipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Tip", detail));
initStatusPane(failedTipLabel, failedIconLabel, failedLabel, failedButton, body, FAILED, failedPane);
}
@ -381,6 +421,7 @@ public class VcsMovePanel extends BasicPane {
private class MoveWorker extends SwingWorker<Boolean, Integer> {
private VcsMoveStrategy strategy;
private String detail = StringUtils.EMPTY;
public MoveWorker(VcsMoveStrategy strategy) {
this.strategy = strategy;
@ -403,6 +444,7 @@ public class VcsMovePanel extends BasicPane {
}, strategy);
} catch (Exception e) {
VcsMoveService.getInstance().stopMoving();
detail = VcsExceptionUtils.createDetailByException(e);
return false;
}
return true;
@ -421,8 +463,9 @@ public class VcsMovePanel extends BasicPane {
initSuccessPane();
VcsMovePanel.this.getParentCard().show(getParentPane(), SUCCESS);
VcsHelper.getInstance().updateLegacyMode();
DesignerFrameFileDealerPane.getInstance().refreshDockingView();
} else {
initFailedPane();
initFailedPane(detail);
VcsMovePanel.this.getParentCard().show(getParentPane(), FAILED);
FineLoggerFactory.getLogger().error("[VcsV2] Vcs move failed!");
}

21
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsNewPane.java

@ -9,7 +9,7 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.vcs.TableValueOperator;
import com.fr.design.mainframe.vcs.VcsService;
import com.fr.design.mainframe.vcs.VcsOperatorWorker;
import com.fr.design.mainframe.vcs.VcsTableEntity;
import com.fr.design.mainframe.vcs.common.VcsCacheFileNodeFile;
import com.fr.design.mainframe.vcs.common.VcsHelper;
@ -111,8 +111,9 @@ public class VcsNewPane extends RecyclePane {
}
};
this.operatorPane = createOperatorPane();
this.model.setDefaultEditor(VcsOperatorPane.class, operatorPane);
this.model.setDefaultRenderer(VcsOperatorPane.class, operatorPane);
this.model.setDefaultEditor(VcsOperatorPane.class, new VcsCellEditor(createOperatorPane()));
this.model.setDefaultRenderer(VcsOperatorPane.class, new VcsCellRender(createOperatorPane()));
this.model.setDefaultRenderer(UILabel.class, new ToolTipTableCellRenderer());
}
@ -128,8 +129,11 @@ public class VcsNewPane extends RecyclePane {
*/
public VcsOperatorPane createOperatorPane() {
restore = new UILabel(RESTORE_ICON);
restore.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Restore"));
delete = new UILabel(DELETE_ICON);
delete.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Delete"));
preview = new UILabel(PREVIEW_ICON);
preview.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Preview"));
initPreviewListener();
initDeleteListener();
initRestoreListener();
@ -156,6 +160,7 @@ public class VcsNewPane extends RecyclePane {
JOptionPane.QUESTION_MESSAGE);
if (selVal == JOptionPane.YES_OPTION) {
restoreEntity(entity);
VcsNewPane.this.saveSettingAndCloseDialog();
}
}
}
@ -209,7 +214,7 @@ public class VcsNewPane extends RecyclePane {
if (selVal == JOptionPane.YES_OPTION) {
model.getList().remove(o);
model.fireTableDataChanged();
VcsService.getInstance().deleteEntity(entity.getFilename(), entity.getVersion());
VcsOperatorWorker.createDeleteWorker().deleteTargetVersion(entity);
}
}
}
@ -225,6 +230,7 @@ public class VcsNewPane extends RecyclePane {
if (o instanceof VcsTableEntity) {
VcsEntity entity = ((VcsTableEntity) o).getEntity();
previewEntity(entity);
VcsNewPane.this.saveSettingAndCloseDialog();
}
}
});
@ -329,11 +335,16 @@ public class VcsNewPane extends RecyclePane {
@Override
public void doOK() {
entity.setCommitMsg(getMsgTestArea().getText());
VcsService.getInstance().updateEntityAnnotation(entity);
VcsOperatorWorker.createUpdateWorker().updateEntityAnnotation(entity);
setVisible(false);
model.fireTableDataChanged();
}
};
dialog.setVisible(true);
}
@Override
protected boolean needIcon4Head(int col) {
return col != 0 && col != OPERATOR_COL;
}
}

37
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsOperatorPane.java

@ -3,20 +3,15 @@ package com.fr.design.mainframe.vcs.ui;
import com.fr.design.layout.FRGUIPaneFactory;
import javax.swing.AbstractCellEditor;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.util.List;
import java.util.List;
import static com.fr.design.mainframe.vcs.ui.AbstractSupportSelectTablePane.DEFAULT_SELECT_TABLE_ROW_COLOR;
/**
* 操作面板用于置放常用的操作label
@ -27,37 +22,19 @@ import static com.fr.design.mainframe.vcs.ui.AbstractSupportSelectTablePane.DEFA
* @since 11.0
* Created on 2023/7/13
*/
public class VcsOperatorPane extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private JPanel contentPane;
private static final Color DETAIL_FONT_COLOR = new Color(65, 155, 249);
public class VcsOperatorPane extends JPanel {
public VcsOperatorPane(List<JComponent> iconJComponentMap) {
init(iconJComponentMap);
}
private void init(List<JComponent> iconJComponentMap) {
contentPane = new JPanel(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout());
this.setLayout(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout());
for (JComponent value : iconJComponentMap) {
value.setForeground(DETAIL_FONT_COLOR);
value.setCursor(new Cursor(Cursor.HAND_CURSOR));
contentPane.add(value);
this.add(value);
}
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
return contentPane;
}
@Override
public Object getCellEditorValue() {
return contentPane;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
contentPane.setBackground(isSelected ? DEFAULT_SELECT_TABLE_ROW_COLOR : Color.WHITE);
return contentPane;
}
}

81
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsProgressDialog.java

@ -0,0 +1,81 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.iprogressbar.ModernUIProgressBarUI;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.stable.StringUtils;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import static java.awt.Component.CENTER_ALIGNMENT;
/**
* Vcs操作进度条面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/18
*/
public class VcsProgressDialog{
private JProgressBar progressBar = new JProgressBar();
private UILabel tipLabel;
private BasicPane processPane;
private BasicDialog dialog;
public VcsProgressDialog(String title, String dealingStr) {
processPane = new BasicPane() {
@Override
protected String title4PopupWindow() {
return title;
}
};
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
progressBar.setStringPainted(true);
progressBar.setUI(new ModernUIProgressBarUI());
progressBar.setBorderPainted(false);
progressBar.setOpaque(false);
progressBar.setBorder(null);
progressBar.setSize(BasicDialog.MEDIUM);
progressBar.setValue(0);
body.add(progressBar);
body.add(new UILabel(StringUtils.BLANK));
tipLabel = new UILabel(dealingStr);
tipLabel.setAlignmentX(CENTER_ALIGNMENT);
body.add(tipLabel);
processPane.add(body);
processPane.setLayout(FRGUIPaneFactory.createCenterLayout(body, 0.5f, 0.5f));
}
/**
* 展示面板
*
*/
public void showDialog() {
dialog = processPane.showSmallWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
}
/**
* 关闭面板
*
*/
public void closeDialog() {
dialog.setVisible(false);
}
public JProgressBar getProgressBar() {
return progressBar;
}
public void setProgressBar(JProgressBar progressBar) {
this.progressBar = progressBar;
}
}

13
designer-base/src/main/java/com/fr/design/mainframe/widget/editors/DataBindingEditor.java

@ -29,8 +29,8 @@ public class DataBindingEditor extends Editor<DataBinding> {
private final static int HORI_GAP = 1;
private final static int VER_GAP = 7;
private TableDataComboBox tableDataComboBox;
private LazyComboBox columnNameComboBox;
protected TableDataComboBox tableDataComboBox;
protected LazyComboBox columnNameComboBox;
private ItemListener tableDataComboBoxListener = new ItemListener() {
public void itemStateChanged(ItemEvent evt) {
boolean isInit = columnNameComboBox.getSelectedIndex() == -1;
@ -87,9 +87,16 @@ public class DataBindingEditor extends Editor<DataBinding> {
}
});
columnNameComboBox.setEditable(true);
addComboBoxesAndSetPosition();
columnNameComboBox.addItemListener(columnNameComboboxListener);
}
/**
* 根据需求不同调整下拉框的位置
*/
protected void addComboBoxesAndSetPosition() {
this.add(tableDataComboBox, BorderLayout.NORTH);
this.add(columnNameComboBox, BorderLayout.CENTER);
columnNameComboBox.addItemListener(columnNameComboboxListener);
}
protected TableDataSource getTableDataSource() {

20
designer-base/src/main/java/com/fr/design/mainframe/widget/editors/WidgetValueEditor.java

@ -5,6 +5,7 @@
package com.fr.design.mainframe.widget.editors;
import java.awt.Component;
import java.awt.BorderLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@ -30,6 +31,7 @@ public class WidgetValueEditor extends AbstractPropertyEditor {
/**
* 根据类型创建
* 服务器 - 控件管理
* @param type 类型
* @param onlyServer 是否是服务器
* @return 编辑器
@ -41,7 +43,7 @@ public class WidgetValueEditor extends AbstractPropertyEditor {
case DataControl.TYPE_FORMULA:
return new FormulaEditor(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Parameter_Formula"));
case DataControl.TYPE_DATABINDING:
return onlyServer ? new ServerDataBindingEditor() : new DataBindingEditor();
return onlyServer ? new WidgetValueServerDataBindingEditor() : new WidgetValueDataBindingEditor();
case DataControl.TYPE_STRING:
return new TextEditor();
case DataControl.TYPE_BOOLEAN:
@ -70,6 +72,22 @@ public class WidgetValueEditor extends AbstractPropertyEditor {
}
return editor;
}
private static class WidgetValueDataBindingEditor extends DataBindingEditor {
@Override
protected void addComboBoxesAndSetPosition() {
this.add(tableDataComboBox, BorderLayout.CENTER);
this.add(columnNameComboBox, BorderLayout.EAST);
}
}
private static class WidgetValueServerDataBindingEditor extends ServerDataBindingEditor {
@Override
protected void addComboBoxesAndSetPosition() {
this.add(tableDataComboBox, BorderLayout.CENTER);
this.add(columnNameComboBox, BorderLayout.EAST);
}
}
public WidgetValueEditor(Object o) {
this(o, false);

4
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_sort_normal.svg

@ -0,0 +1,4 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.2462 6.17654C14.3492 6.30778 14.2557 6.5 14.0889 6.5H11.9999V13.9768C11.9999 14.0873 11.9104 14.1768 11.7999 14.1768H11.1999C11.0895 14.1768 10.9999 14.0873 10.9999 13.9768V6.5H8.91119C8.74436 6.5 8.65086 6.30779 8.75384 6.17654L11.3426 2.87732C11.4227 2.77527 11.5772 2.77527 11.6573 2.87731L14.2462 6.17654Z" fill="#333334"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.04297 10.801C2.93999 10.6698 3.03349 10.4775 3.20032 10.4775H5.28927V3.00074C5.28927 2.89028 5.37881 2.80074 5.48927 2.80074H6.08927C6.19972 2.80074 6.28927 2.89028 6.28927 3.00074V10.4775H8.378C8.54482 10.4775 8.63832 10.6698 8.53534 10.801L5.94661 14.1002C5.86653 14.2023 5.712 14.2023 5.63192 14.1002L3.04297 10.801Z" fill="#333334"/>
</svg>

After

Width:  |  Height:  |  Size: 874 B

27
designer-form/src/main/java/com/fr/design/designer/creator/XEditorHolder.java

@ -44,9 +44,7 @@ public class XEditorHolder extends XWidgetCreator {
ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this);
editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter);
Rectangle rect = this.getBounds();
int min = rect.x + rect.width / 2 - editingMouseListener.getMinMoveSize();
int max = rect.x + rect.width / 2 + editingMouseListener.getMinMoveSize();
if (e.getX() > min && e.getX() < max) {
if (checkMouseEditRangeValid(e, rect, editingMouseListener)) {
ToolTipEditor.getInstance().showToolTip((XEditorHolder) this, e.getXOnScreen(),
e.getYOnScreen());
}
@ -54,6 +52,29 @@ public class XEditorHolder extends XWidgetCreator {
}
}
/**
* 判断当前鼠标事件是否在可编辑区域内
*
* @param e 鼠标事件
* @param rect 区域
* @param editingMouseListener 位置处理器
* @return 是否位于可编辑区
*/
private boolean checkMouseEditRangeValid(MouseEvent e, Rectangle rect, EditingMouseListener editingMouseListener) {
int horizontalValue = editingMouseListener.getDesigner().getHorizontalScaleValue();
int verticalValue = editingMouseListener.getDesigner().getVerticalScaleValue();
int minMoveSize = editingMouseListener.getMinMoveSize();
int minHorizontal = rect.x + rect.width / 2 - minMoveSize - horizontalValue;
int maxHorizontal = rect.x + rect.width / 2 + minMoveSize - horizontalValue;
int minVertical = rect.y + rect.height / 2 - minMoveSize - verticalValue;
int maxVertical = rect.y + rect.height / 2 + minMoveSize - verticalValue;
boolean xRangeValid = e.getX() > minHorizontal && e.getX() < maxHorizontal;
boolean yRangeValid = e.getY() > minVertical && e.getY() < maxVertical;
return xRangeValid && yRangeValid;
}
@Override
protected String getIconName() {
return "text_field_16.png";

23
designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java

@ -279,9 +279,7 @@ public class EditingMouseListener extends MouseInputAdapter {
if (component instanceof XEditorHolder) {
XEditorHolder xcreator = (XEditorHolder) component;
Rectangle rect = xcreator.getBounds();
int min = rect.x + rect.width / 2 - minMoveSize;
int max = rect.x + rect.width / 2 + minMoveSize;
if (e.getX() > min && e.getX() < max) {
if (checkCreatorRangeValid(e, rect)) {
if (designer.getCursor().getType() != Cursor.HAND_CURSOR) {
designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
@ -673,8 +671,8 @@ public class EditingMouseListener extends MouseInputAdapter {
currentEditor = designerEditor;
currentXCreator = creator;
Rectangle bounds = new Rectangle(1, 1, creator.getWidth() - 2, creator.getHeight() - 2);
bounds.x += (rect.x - designer.getArea().getHorizontalValue());
bounds.y += (rect.y - designer.getArea().getVerticalValue());
bounds.x += (rect.x - designer.getHorizontalScaleValue());
bounds.y += (rect.y - designer.getVerticalScaleValue());
designerEditor.getEditorTarget().setBounds(bounds);
designer.add(designerEditor.getEditorTarget());
designer.invalidate();
@ -747,4 +745,19 @@ public class EditingMouseListener extends MouseInputAdapter {
refreshTopXCreator(false);
}
/**
* 判断当前鼠标移动事件是否在Creator有效范围内
*/
private boolean checkCreatorRangeValid(MouseEvent e, Rectangle rect) {
int horizontalValue = designer.getHorizontalScaleValue();
int verticalValue = designer.getVerticalScaleValue();
int minHorizontal = rect.x + rect.width / 2 - minMoveSize - horizontalValue;
int maxHorizontal = rect.x + rect.width / 2 + minMoveSize - horizontalValue;
int minVertical = rect.y + rect.height / 2 - minMoveSize - verticalValue;
int maxVertical = rect.y + rect.height / 2 + minMoveSize - verticalValue;
boolean xRangeValid = e.getX() > minHorizontal && e.getX() < maxHorizontal;
boolean yRangeValid = e.getY() > minVertical && e.getY() < maxVertical;
return xRangeValid && yRangeValid;
}
}

2
designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java

@ -1208,7 +1208,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
}
public XLayoutContainer getRootContainer(int y) {
XLayoutContainer container = y < paraHeight - formArea.getVerticalValue() ? paraComponent : rootComponent;
XLayoutContainer container = y < paraHeight - formArea.getVerticalValue() / scale ? paraComponent : rootComponent;
if (container == null) {
container = rootComponent;
}

2
designer-form/src/main/java/com/fr/design/widget/ui/designer/component/FormWidgetValuePane.java

@ -63,7 +63,7 @@ public class FormWidgetValuePane extends JPanel {
/**
* 根据类型创建
*
* 设计器右侧控件设置 - 属性
* @param type 类型
* @param onlyServer 是否是服务器
* @return 编辑器

Loading…
Cancel
Save