Browse Source

REPORT-14835

模板版本管理优化及内置
research/10.0
XiaXiang 6 years ago
parent
commit
8141697e3f
  1. 70
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  2. 74
      designer-base/src/main/java/com/fr/design/mainframe/toolbar/VcsConfig.java
  3. 17
      designer-base/src/main/java/com/fr/design/mainframe/toolbar/VcsContext.java
  4. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_back_normal@2x.png
  5. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_delete.png
  6. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_delete@2x.png
  7. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_edit.png
  8. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_edit@2x.png
  9. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_filter@1x.png
  10. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_filter@2x.png
  11. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_list_disabled.png
  12. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_list_disabled@2x.png
  13. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_list_normal@2x.png
  14. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_revert.png
  15. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_revert@2x.png
  16. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_save_disabled.png
  17. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_save_disabled@2x.png
  18. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_save_normal@2x.png
  19. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_user@1x.png
  20. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_user@2x.png
  21. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/vcs_back.png
  22. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/vcs_list.png
  23. BIN
      designer-base/src/main/java/com/fr/design/mainframe/vcs/images/vcs_save.png
  24. 74
      designer-base/src/main/java/com/fr/design/mainframe/vcs/proxy/VcsCacheFileNodeFileProxy.java
  25. 83
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java
  26. 43
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellRender.java
  27. 77
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionDialog.java
  28. 20
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionFirstRowPanel.java
  29. 148
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionRowPanel.java
  30. 86
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionTablePanel.java
  31. 187
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java
  32. 52
      designer-realize/src/main/java/com/fr/start/Designer.java

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

@ -26,6 +26,8 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper; import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.toolbar.VcsConfig;
import com.fr.design.mainframe.vcs.ui.FileVersionsPanel;
import com.fr.design.menu.KeySetUtils; import com.fr.design.menu.KeySetUtils;
import com.fr.design.menu.ShortCut; import com.fr.design.menu.ShortCut;
import com.fr.design.menu.ToolBarDef; import com.fr.design.menu.ToolBarDef;
@ -43,9 +45,13 @@ import com.fr.plugin.manage.PluginFilter;
import com.fr.plugin.observer.PluginEvent; import com.fr.plugin.observer.PluginEvent;
import com.fr.plugin.observer.PluginEventListener; import com.fr.plugin.observer.PluginEventListener;
import com.fr.stable.CoreConstants; import com.fr.stable.CoreConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.third.org.apache.commons.io.FilenameUtils; import com.fr.third.org.apache.commons.io.FilenameUtils;
import com.fr.third.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.common.Constants;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.JDialog; import javax.swing.JDialog;
@ -111,6 +117,8 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
private DelFileAction delFileAction = new DelFileAction(); private DelFileAction delFileAction = new DelFileAction();
private VcsAction vcsAction = new VcsAction();
/** /**
* 刷新 * 刷新
@ -191,7 +199,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
if (WorkContext.getCurrent().isLocal()) { if (WorkContext.getCurrent().isLocal()) {
toolbarDef.addShortCut(showInExplorerAction); toolbarDef.addShortCut(showInExplorerAction);
} }
toolbarDef.addShortCut(renameAction, delFileAction); toolbarDef.addShortCut(renameAction, delFileAction, vcsAction);
Set<ShortCut> extraShortCuts = ExtraDesignClassManager.getInstance().getExtraShortCuts(); Set<ShortCut> extraShortCuts = ExtraDesignClassManager.getInstance().getExtraShortCuts();
for (ShortCut shortCut : extraShortCuts) { for (ShortCut shortCut : extraShortCuts) {
toolbarDef.addShortCut(shortCut); toolbarDef.addShortCut(shortCut);
@ -209,6 +217,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
showInExplorerAction.setEnabled(false); showInExplorerAction.setEnabled(false);
renameAction.setEnabled(false); renameAction.setEnabled(false);
delFileAction.setEnabled(false); delFileAction.setEnabled(false);
vcsAction.setEnabled(false);
this.repaint(); this.repaint();
} }
@ -273,6 +282,63 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
} }
/**
* 版本管理
*/
private class VcsAction extends UpdateAction {
public VcsAction() {
this.setName(Toolkit.i18nText("Plugin-VCS_Title"));
this.setSmallIcon(Constants.VCS_LIST_PNG);
}
@Override
public void actionPerformed(ActionEvent e) {
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
path = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, path);
boolean isCurrentEditing = isCurrentEditing(path);
// 如果模板正在编辑,保存后再打开版本管理
if (isCurrentEditing) {
saveCurrentEditingTemplate();
}
// 如果模板已经打开了,关掉,避免出现2个同名tab(1个是模板,1个是版本)
closeOpendTemplate(path, isCurrentEditing);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(VcsConfig.class);
FileVersionsPanel fileVersionTablePanel = context.getBean(FileVersionsPanel.class);
fileVersionTablePanel.showFileVersionsPane();
}
private void closeOpendTemplate(String path, boolean isCurrentEditing) {
for (JTemplate<?, ?> jTemplate : HistoryTemplateListCache.getInstance().getHistoryList()) {
if (ComparatorUtils.equals(jTemplate.getEditingFILE().getPath(), path)) {
if (isCurrentEditing) {
MutilTempalteTabPane.getInstance().setIsCloseCurrent(true);
}
MutilTempalteTabPane.getInstance().closeFormat(jTemplate);
MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(jTemplate);
return;
}
}
}
}
private void saveCurrentEditingTemplate() {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
jt.stopEditing();
jt.saveTemplate();
jt.requestFocus();
}
private boolean isCurrentEditing(String path) {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
String editing = jt.getEditingFILE().getPath();
return ComparatorUtils.equals(editing, path);
}
/** /**
* 在系统资源管理器中打开 * 在系统资源管理器中打开
*/ */
@ -386,11 +452,11 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
newFolderAction.setEnabled(singleSelected); newFolderAction.setEnabled(singleSelected);
renameAction.setEnabled(singleSelected); renameAction.setEnabled(singleSelected);
showInExplorerAction.setEnabled(singleSelected); showInExplorerAction.setEnabled(singleSelected);
vcsAction.setEnabled(singleSelected);
// 删除操作在至少选中一个时可用 // 删除操作在至少选中一个时可用
boolean selected = selectedPathNum > 0; boolean selected = selectedPathNum > 0;
delFileAction.setEnabled(selected); delFileAction.setEnabled(selected);
// 刷新操作始终可用 // 刷新操作始终可用
refreshTreeAction.setEnabled(true); refreshTreeAction.setEnabled(true);

74
designer-base/src/main/java/com/fr/design/mainframe/toolbar/VcsConfig.java

@ -0,0 +1,74 @@
package com.fr.design.mainframe.toolbar;
import com.fr.design.mainframe.vcs.ui.FileVersionCellEditor;
import com.fr.design.mainframe.vcs.ui.FileVersionCellRender;
import com.fr.design.mainframe.vcs.ui.FileVersionFirstRowPanel;
import com.fr.design.mainframe.vcs.ui.FileVersionRowPanel;
import com.fr.design.mainframe.vcs.ui.FileVersionTablePanel;
import com.fr.design.mainframe.vcs.ui.FileVersionsPanel;
import com.fr.third.javax.inject.Singleton;
import com.fr.third.springframework.context.annotation.Bean;
import com.fr.third.springframework.context.annotation.ComponentScan;
import com.fr.third.springframework.context.annotation.Configuration;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.workspace.server.vcs.VcsOperatorImpl;
import com.fr.workspace.server.vcs.filesystem.VcsFileSystem;
import com.fr.workspace.server.vcs.git.FineGit;
/**
* Created by XiaXiang on 2019/4/16.
*/
@Configuration
@ComponentScan({"com.fr.workspace.server.vcs", "com.fr.design.mainframe.vcs"})
public class VcsConfig {
@Bean
@Singleton
public FileVersionsPanel fileVersionsPanel() {
return new FileVersionsPanel(fileVersionTablePanel());
}
@Bean
@Singleton
public FileVersionTablePanel fileVersionTablePanel() {
return new FileVersionTablePanel(vcsOperator(), fileVersionCellEditor(), fileVersionCellRender());
}
@Bean
@Singleton
public FileVersionCellEditor fileVersionCellEditor() {
return new FileVersionCellEditor(fileVersionFirstRowPanel(), fileVersionRowPanel(), vcsOperator());
}
@Bean
@Singleton
public FileVersionFirstRowPanel fileVersionFirstRowPanel() {
return new FileVersionFirstRowPanel();
}
@Bean
public FileVersionRowPanel fileVersionRowPanel() {
return new FileVersionRowPanel(vcsOperator());
}
@Bean
@Singleton
public FileVersionCellRender fileVersionCellRender() {
return new FileVersionCellRender(fileVersionFirstRowPanel(), fileVersionRowPanel());
}
@Bean
@Singleton
public VcsOperator vcsOperator() {
return new VcsOperatorImpl(vcsFileSystem(), new FineGit(vcsFileSystem().getVcsHistoryPath()));
}
@Bean
@Singleton
public VcsFileSystem vcsFileSystem() {
return new VcsFileSystem(WorkContext.getCurrent());
}
}

17
designer-base/src/main/java/com/fr/design/mainframe/toolbar/VcsContext.java

@ -0,0 +1,17 @@
package com.fr.design.mainframe.toolbar;
import com.fr.third.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Created by XiaXiang on 2019/4/20.
*/
public class VcsContext extends AnnotationConfigApplicationContext {
public static final VcsContext INSTANCE = new VcsContext();
public static VcsContext get() {
return INSTANCE;
}
}

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_back_normal@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_delete.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_delete@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_edit.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_edit@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_filter@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_filter@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_list_disabled.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_list_disabled@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_list_normal@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_revert.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_revert@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_save_disabled.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_save_disabled@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_save_normal@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 908 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_user@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/icon_user@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/vcs_back.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/vcs_list.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

BIN
designer-base/src/main/java/com/fr/design/mainframe/vcs/images/vcs_save.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

74
designer-base/src/main/java/com/fr/design/mainframe/vcs/proxy/VcsCacheFileNodeFileProxy.java

@ -0,0 +1,74 @@
package com.fr.design.mainframe.vcs.proxy;
import com.fr.base.io.XMLEncryptUtils;
import com.fr.file.FileNodeFILE;
import com.fr.file.filetree.FileNode;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StableUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.resource.WorkResource;
import com.fr.workspace.resource.WorkResourceOutputStream;
import com.fr.workspace.server.vcs.common.Constants;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Created by hzzz on 2017/12/21.
*/
public class VcsCacheFileNodeFileProxy extends FileNodeFILE {
private final FileNode node;
public VcsCacheFileNodeFileProxy(FileNode node) {
super(node);
this.node = node;
}
/**
* 和FileNodeFILE中一样只是去掉了必须以reportlets开头的限制改为vcs开头
*
* @return
* @throws Exception
*/
@Override
public InputStream asInputStream() throws Exception {
if (node == null) {
return null;
}
String envPath = node.getEnvPath();
// envPath必须以vcs开头
if (!envPath.startsWith(Constants.VCS_CACHE_DIR)) {
return null;
}
InputStream in = WorkContext.getCurrent().get(WorkResource.class)
.openStream(StableUtils.pathJoin(Constants.VCS_CACHE_DIR, envPath.substring(Constants.VCS_CACHE_DIR.length() + 1)));
return envPath.endsWith(".cpt") || envPath.endsWith(".frm")
? XMLEncryptUtils.decodeInputStream(in) : in;
}
/**
* 和FileNodeFILE中一样只是去掉了必须以reportlets开头的限制改为vcs开头
*
* @return
* @throws Exception
*/
@Override
public OutputStream asOutputStream() throws Exception {
if (ComparatorUtils.equals(node, null)) {
return null;
}
String envPath = node.getEnvPath();
// envPath必须以reportlets开头
if (!envPath.startsWith(Constants.VCS_CACHE_DIR)) {
return null;
}
return new WorkResourceOutputStream(StableUtils.pathJoin(Constants.VCS_CACHE_DIR, envPath.substring(Constants.VCS_CACHE_DIR.length() + 1)));
}
}

83
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java

@ -0,0 +1,83 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.vcs.proxy.VcsCacheFileNodeFileProxy;
import com.fr.file.filetree.FileNode;
import com.fr.log.FineLoggerFactory;
import com.fr.report.entity.VcsEntity;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.workspace.server.vcs.common.Constants;
import javax.swing.AbstractCellEditor;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import java.awt.Component;
public class FileVersionCellEditor extends AbstractCellEditor implements TableCellEditor {
private final VcsOperator vcs;
//第一行
private final JPanel firstRowPanel;
//其余行
private final FileVersionRowPanel renderAndEditor;
public FileVersionCellEditor(FileVersionFirstRowPanel firstRowPanel, FileVersionRowPanel renderAndEditor, VcsOperator vcs) {
this.vcs = vcs;
this.firstRowPanel = firstRowPanel;
this.renderAndEditor = renderAndEditor;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
String fileOfVersion = null;
Component editor = row == 0 ? firstRowPanel : renderAndEditor;
if (isSelected) {
return editor;
} else if (row == 0) {
//TODO path "/"
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
try {
fileOfVersion = vcs.getFileOfCurrent(path.replaceFirst("/", ""));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
} else {
renderAndEditor.update((VcsEntity) value);
try {
fileOfVersion = vcs.getFileOfFileVersion(((VcsEntity) value).getFilename(), ((VcsEntity) value).getVersion());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
editor.setBackground(Constants.TABLE_SELECT_BACKGROUND);
if (StringUtils.isNotEmpty(fileOfVersion)) {
//先关闭当前打开的模板版本
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
jt.stopEditing();
MutilTempalteTabPane.getInstance().setIsCloseCurrent(true);
MutilTempalteTabPane.getInstance().closeFormat(jt);
MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(jt);
//再打开cache中的模板
DesignerContext.getDesignerFrame().openTemplate(new VcsCacheFileNodeFileProxy(new FileNode(fileOfVersion, false)));
}
double height = editor.getPreferredSize().getHeight();
if (table.getRowHeight(row) != height) {
table.setRowHeight(row, (int) height);
}
return editor;
}
@Override
public Object getCellEditorValue() {
return renderAndEditor.getFileVersion();
}
}

43
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellRender.java

@ -0,0 +1,43 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.report.entity.VcsEntity;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
import java.awt.Component;
import static com.fr.design.constants.UIConstants.TREE_BACKGROUND;
import static com.fr.workspace.server.vcs.common.Constants.TABLE_SELECT_BACKGROUND;
public class FileVersionCellRender implements TableCellRenderer {
//第一行
private final JPanel firstRowPanel;
//其余行
private final FileVersionRowPanel render;
public FileVersionCellRender(FileVersionFirstRowPanel firstRowPanel, FileVersionRowPanel render) {
this.render = render;
this.firstRowPanel = firstRowPanel;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component editor = row == 0 ? firstRowPanel : render;
// https://stackoverflow.com/questions/3054775/jtable-strange-behavior-from-getaccessiblechild-method-resulting-in-null-point
if (value != null) {
render.update((VcsEntity) value);
}
editor.setBackground(isSelected ? TABLE_SELECT_BACKGROUND : TREE_BACKGROUND);
double height = editor.getPreferredSize().getHeight();
if (table.getRowHeight(row) != height) {
table.setRowHeight(row, (int) height);
}
return editor;
}
}

77
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionDialog.java

@ -0,0 +1,77 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.dialog.UIDialog;
import com.fr.design.editor.editor.DateEditor;
import com.fr.design.gui.date.UIDatePicker;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import static com.fr.workspace.server.vcs.common.Constants.EMPTY_BORDER;
import static com.fr.workspace.server.vcs.common.Constants.EMPTY_BORDER_BOTTOM;
public class FileVersionDialog extends UIDialog {
private UIButton okBtn = new UIButton("确定");
private UIButton cancelBtn = new UIButton("取消");
public FileVersionDialog(Frame frame) {
super(frame);
setUndecorated(true);
JPanel panel = new JPanel(new BorderLayout());
Box box0 = Box.createHorizontalBox();
box0.setBorder(EMPTY_BORDER_BOTTOM);
box0.add(new UILabel("生成日期"));
box0.add(Box.createHorizontalGlue());
box0.add(new DateEditor(new Date(), true, "生成日期", UIDatePicker.STYLE_CN_DATE1));
Box box1 = Box.createHorizontalBox();
box1.setBorder(EMPTY_BORDER_BOTTOM);
box1.add(new UILabel("备注关键词 "));
box1.add(new UITextField());
Box box2 = Box.createHorizontalBox();
box2.add(Box.createHorizontalGlue());
box2.setBorder(EMPTY_BORDER);
box2.add(okBtn);
box2.add(cancelBtn);
okBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
FileVersionDialog.this.setVisible(false);
}
});
cancelBtn.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
FileVersionDialog.this.setVisible(false);
}
});
panel.add(box0, BorderLayout.NORTH);
panel.add(box1, BorderLayout.CENTER);
panel.add(box2, BorderLayout.SOUTH);
add(panel);
setSize(new Dimension(220, 100));
centerWindow(this);
}
private void centerWindow(Window window) {
window.setLocation(0, 95);
}
@Override
public void checkValid() throws Exception {
}
}

20
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionFirstRowPanel.java

@ -0,0 +1,20 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.gui.ilable.UILabel;
import javax.swing.Box;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.BorderLayout;
public class FileVersionFirstRowPanel extends JPanel {
public FileVersionFirstRowPanel() {
super(new BorderLayout());
Box upPane = Box.createVerticalBox();
upPane.setBorder(new EmptyBorder(5, 10, 5, 10));
upPane.add(new UILabel("本地用户"));
add(upPane, BorderLayout.CENTER);
}
}

148
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionRowPanel.java

@ -0,0 +1,148 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.gui.frpane.UITextPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.toolbar.VcsConfig;
import com.fr.log.FineLoggerFactory;
import com.fr.report.entity.VcsEntity;
import com.fr.stable.StringUtils;
import com.fr.third.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.workspace.server.vcs.common.Constants;
import javax.swing.Box;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
public class FileVersionRowPanel extends JPanel {
private final VcsOperator<VcsEntity> vcs;
private VcsEntity fileVersion;
private UILabel versionLabel = new UILabel();
private UILabel usernameLabel = new UILabel("", Constants.VCS_USER_PNG, SwingConstants.LEFT);
private UITextPane timeAndMsgLabel = new UITextPane();
private UILabel timeLabel = new UILabel();
@SuppressWarnings("unchecked")
public FileVersionRowPanel(final VcsOperator vcsOperator) {
this.vcs = vcsOperator;
setLayout(new BorderLayout());
// version + username
Box upPane = Box.createHorizontalBox();
upPane.setBorder(Constants.EMPTY_BORDER);
upPane.add(versionLabel);
upPane.add(Box.createHorizontalGlue());
// msg
timeAndMsgLabel.setBorder(Constants.EMPTY_BORDER);
timeAndMsgLabel.setOpaque(false);
timeAndMsgLabel.setBackground(new Color(0, 0, 0, 0));
timeAndMsgLabel.setEditable(false);
// confirm + delete
UIButton confirmBtn = new UIButton(Constants.VCS_REVERT);
confirmBtn.set4ToolbarButton();
confirmBtn.setToolTipText(Toolkit.i18nText("Plugin-VCS_Version_Revert"));
confirmBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
if (JOptionPane.showConfirmDialog(null, Toolkit.i18nText("Plugin-VCS_Version_Revert_Confirm"), Toolkit.i18nText("Plugin-VCS_Version_Revert_Title"),
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
try {
vcs.rollbackTo(fileVersion);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(VcsConfig.class);
context.getBean(FileVersionsPanel.class).exitVcs(fileVersion.getFilename());
}
}
});
UIButton deleteBtn = new UIButton(Constants.VCS_DELETE_PNG);
deleteBtn.set4ToolbarButton();
deleteBtn.setToolTipText(Toolkit.i18nText("Plugin-VCS_Version_Delete"));
deleteBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
if (JOptionPane.showConfirmDialog(null, Toolkit.i18nText("Plugin-VCS_Version_Delete_Confirm"), Toolkit.i18nText("FR-Designer_Remove"),
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
//TODO refactor
try {
vcs.deleteVersion(fileVersion.getFilename(), fileVersion.getVersion());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
FileVersionTablePanel table = (FileVersionTablePanel) (FileVersionRowPanel.this.getParent());
table.updateModel(table.getSelectedRow() - 1);
}
}
});
UIButton editBtn = new UIButton(Constants.VCS_EDIT_PNG);
editBtn.set4ToolbarButton();
editBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showEditDialog();
}
});
upPane.add(editBtn);
upPane.add(confirmBtn);
upPane.add(deleteBtn);
Box downPane = Box.createHorizontalBox();
downPane.add(usernameLabel);
downPane.setBorder(Constants.EMPTY_BORDER_BOTTOM);
downPane.add(Box.createHorizontalGlue());
downPane.add(timeLabel);
add(upPane, BorderLayout.NORTH);
add(timeAndMsgLabel, BorderLayout.CENTER);
add(downPane, BorderLayout.SOUTH);
}
private void showEditDialog() {
}
public void update(final VcsEntity fileVersion) {
this.fileVersion = fileVersion;
versionLabel.setText(String.format("V.%s", fileVersion.getVersion()));
usernameLabel.setText(fileVersion.getUsername());
timeAndMsgLabel.setText(StringUtils.EMPTY);
timeLabel.setText(timeStr(fileVersion.getTime()));
try {
StyledDocument doc = timeAndMsgLabel.getStyledDocument();
Style style = timeAndMsgLabel.getLogicalStyle();
StyleConstants.setForeground(style, Color.BLACK);
doc.insertString(doc.getLength(), " " + fileVersion.getCommitMsg(), style);
} catch (BadLocationException e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
private String timeStr(Date time) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return simpleDateFormat.format(time);
}
public VcsEntity getFileVersion() {
return fileVersion;
}
}

86
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionTablePanel.java

@ -0,0 +1,86 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.log.FineLoggerFactory;
import com.fr.report.entity.VcsEntity;
import com.fr.workspace.server.vcs.VcsOperator;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.util.ArrayList;
import java.util.List;
public class FileVersionTablePanel extends JTable {
private final VcsOperator vcs;
public FileVersionTablePanel(VcsOperator vcs, TableCellEditor tableCellEditor, TableCellRenderer tableCellRenderer) {
super(new Model(new ArrayList<VcsEntity>()));
this.vcs = vcs;
setDefaultRenderer(VcsEntity.class, tableCellRenderer);
setDefaultEditor(VcsEntity.class, tableCellEditor);
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
setTableHeader(null);
setRowHeight(30);
}
public void updateModel(int selectedRow) {
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
//TODO path "/"
List<VcsEntity> vcsEntities = null;
try {
vcsEntities = vcs.getVersions(path.replaceFirst("/", ""));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
if (selectedRow > vcsEntities.size()) {
selectedRow = vcsEntities.size();
}
setModel(new Model(vcsEntities));
editCellAt(selectedRow, 0);
setRowSelectionInterval(selectedRow, selectedRow);
}
private static class Model extends AbstractTableModel {
private List<VcsEntity> vcsEntities;
Model(List<VcsEntity> vcsEntities) {
this.vcsEntities = vcsEntities;
}
public Class getColumnClass(int columnIndex) {
return VcsEntity.class;
}
public int getColumnCount() {
return 1;
}
public int getRowCount() {
return (vcsEntities == null) ? 0 : vcsEntities.size() + 1;
}
public Object getValueAt(int rowIndex, int columnIndex) {
if (rowIndex == 0) {
return null;
}
return (vcsEntities == null) ? null : vcsEntities.get(rowIndex - 1);
}
public boolean isCellEditable(int columnIndex, int rowIndex) {
return true;
}
public List<VcsEntity> getVcsEntities() {
return vcsEntities;
}
}
}

187
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java

@ -0,0 +1,187 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.base.GraphHelper;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.dialog.BasicPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MutilTempalteTabPane;
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.itoolbar.UIToolbar;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.ToolBarNewTemplatePane;
import com.fr.design.mainframe.WestRegionContainerPane;
import com.fr.design.menu.ToolBarDef;
import com.fr.file.FileNodeFILE;
import com.fr.file.filetree.FileNode;
import com.fr.stable.StableUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.server.vcs.common.Constants;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class FileVersionsPanel extends BasicPane {
private static final String ELLIPSIS = "...";
private final FileVersionTablePanel fileVersionsTablePane;
private UILabel titleLabel;
private String templatePath;
private UIButton filterBtn;
private FileVersionDialog versionDialog;
public FileVersionsPanel(FileVersionTablePanel fileVersionTablePanel) {
this.fileVersionsTablePane = fileVersionTablePanel;
initComponents();
}
private void initComponents() {
setLayout(new BorderLayout());
UIToolbar toolbar = ToolBarDef.createJToolBar();
toolbar.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0));
toolbar.setBorderPainted(true);
Box upPane = Box.createHorizontalBox();
UIButton backBtn = new UIButton(Constants.VCS_BACK_PNG);
backBtn.set4ToolbarButton();
backBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
exitVcs(templatePath);
}
});
toolbar.add(backBtn);
filterBtn = new UIButton(Constants.VCS_FILTER_PNG);
filterBtn.set4ToolbarButton();
filterBtn.setHorizontalAlignment(SwingConstants.RIGHT);
filterBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showFilterPane();
}
});
titleLabel = new UILabel() {
@Override
public Dimension getMaximumSize() {
return new Dimension(257, 21);
}
};
upPane.add(titleLabel);
upPane.add(Box.createHorizontalGlue());
upPane.add(filterBtn);
toolbar.add(Box.createHorizontalGlue());
toolbar.add(upPane);
add(toolbar, BorderLayout.NORTH);
UIScrollPane jScrollPane = new UIScrollPane(fileVersionsTablePane);
add(jScrollPane, BorderLayout.CENTER);
}
private void showFilterPane() {
versionDialog = new FileVersionDialog(DesignerContext.getDesignerFrame());
versionDialog.setVisible(true);
}
/**
* 退出版本管理并且打开模板
*
* @param path 被管理的模板的名字
*/
public void exitVcs(String path) {
// 关闭当前打开的版本
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
MutilTempalteTabPane.getInstance().setIsCloseCurrent(true);
MutilTempalteTabPane.getInstance().closeFormat(jt);
MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(jt);
udpateDesignerFrame(true);
final String selectedFilePath = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, path);
DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(selectedFilePath, false)));
}
private void refreshVersionTablePane() {
templatePath = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
String[] paths = StableUtils.pathSplit(templatePath);
String filename = paths[paths.length - 1];
int width = fileVersionsTablePane.getWidth() - 40;
if (getStringWidth(filename) > width) {
filename = getEllipsisName(filename, width);
}
titleLabel.setText(filename);
fileVersionsTablePane.updateModel(1);
}
public void showFileVersionsPane() {
udpateDesignerFrame(false);
refreshVersionTablePane();
}
@Override
protected String title4PopupWindow() {
return null;
}
private void udpateDesignerFrame(boolean isExit) {
// 左上侧面板
WestRegionContainerPane.getInstance().replaceUpPane(
isExit ? DesignerFrameFileDealerPane.getInstance() : this);
DesignModeContext.switchTo(isExit ? com.fr.design.base.mode.DesignerMode.NORMAL : com.fr.design.base.mode.DesignerMode.VCS);
// MutilTempalteTabPane & NewTemplatePane 是否可点
ToolBarNewTemplatePane.getInstance().setButtonGray(!isExit);
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
if (currentEditingTemplate.isJWorkBook()) {
DesignerContext.getDesignerFrame().resetToolkitByPlus(currentEditingTemplate);
}
}
private int getStringWidth(String str) {
return GraphHelper.getFontMetrics(this.getFont()).stringWidth(str);
}
private String getEllipsisName(String name, int maxStringlength) {
//若是名字长度大于能显示的长度,那能显示的文字的最大长度还要减去省略号的最大长度
// int maxellipsislength = maxStringlength - ELLIPSIS.length();
int ellipsisWidth = getStringWidth(ELLIPSIS);
int leftkeyPoint = 0;
int rightKeyPoint = name.length() - 1;
int leftStrWidth = 0;
int rightStrWidth = 0;
while (leftStrWidth + rightStrWidth + ellipsisWidth < maxStringlength) {
if (leftStrWidth <= rightStrWidth) {
leftkeyPoint++;
} else {
rightKeyPoint--;
}
leftStrWidth = getStringWidth(name.substring(0, leftkeyPoint));
rightStrWidth = getStringWidth(name.substring(rightKeyPoint));
if (leftStrWidth + rightStrWidth + ellipsisWidth > maxStringlength) {
if (leftStrWidth <= rightStrWidth) {
rightKeyPoint++;
}
break;
}
}
return name.substring(0, leftkeyPoint) + ELLIPSIS + name.substring(rightKeyPoint);
}
}

52
designer-realize/src/main/java/com/fr/start/Designer.java

@ -12,6 +12,7 @@ import com.fr.design.actions.server.ServerConfigManagerAction;
import com.fr.design.actions.server.StyleListAction; import com.fr.design.actions.server.StyleListAction;
import com.fr.design.actions.server.WidgetManagerAction; import com.fr.design.actions.server.WidgetManagerAction;
import com.fr.design.constants.UIConstants; import com.fr.design.constants.UIConstants;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MutilTempalteTabPane; import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.fun.MenuHandler; import com.fr.design.fun.MenuHandler;
@ -30,6 +31,9 @@ import com.fr.design.mainframe.bbs.UserInfoLabel;
import com.fr.design.mainframe.bbs.UserInfoPane; import com.fr.design.mainframe.bbs.UserInfoPane;
import com.fr.design.mainframe.templateinfo.TemplateInfoCollector; import com.fr.design.mainframe.templateinfo.TemplateInfoCollector;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
import com.fr.design.mainframe.toolbar.VcsConfig;
import com.fr.design.mainframe.vcs.proxy.VcsCacheFileNodeFileProxy;
import com.fr.design.mainframe.vcs.ui.FileVersionTablePanel;
import com.fr.design.menu.KeySetUtils; import com.fr.design.menu.KeySetUtils;
import com.fr.design.menu.MenuDef; import com.fr.design.menu.MenuDef;
import com.fr.design.menu.SeparatorDef; import com.fr.design.menu.SeparatorDef;
@ -49,13 +53,17 @@ import com.fr.stable.ProductConstants;
import com.fr.stable.StableUtils; import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
import com.fr.stable.lifecycle.LifecycleFatalError; import com.fr.stable.lifecycle.LifecycleFatalError;
import com.fr.stable.project.ProjectConstants;
import com.fr.stable.xml.XMLTools; import com.fr.stable.xml.XMLTools;
import com.fr.start.fx.SplashFx; import com.fr.start.fx.SplashFx;
import com.fr.start.jni.SplashMac; import com.fr.start.jni.SplashMac;
import com.fr.start.module.StartupArgs; import com.fr.start.module.StartupArgs;
import com.fr.start.preload.ImagePreLoader; import com.fr.start.preload.ImagePreLoader;
import com.fr.start.server.ServerTray; import com.fr.start.server.ServerTray;
import com.fr.third.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.workspace.server.vcs.common.Constants;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
@ -107,7 +115,6 @@ public class Designer extends BaseDesigner {
System.exit(0); System.exit(0);
return; return;
} }
RestartHelper.deleteRecordFilesWhenStart(); RestartHelper.deleteRecordFilesWhenStart();
preloadResource(); preloadResource();
@ -259,7 +266,7 @@ public class Designer extends BaseDesigner {
*/ */
@Override @Override
public UIButton[] createUp() { public UIButton[] createUp() {
return new UIButton[]{createSaveButton(), createUndoButton(), createRedoButton()}; return new UIButton[]{createSaveButton(), createUndoButton(), createRedoButton(), };
} }
@ -274,11 +281,52 @@ public class Designer extends BaseDesigner {
jt.stopEditing(); jt.stopEditing();
jt.saveTemplate(); jt.saveTemplate();
jt.requestFocus(); jt.requestFocus();
String fileName = getEditingFilename();
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(VcsConfig.class);
VcsOperator vcsOperator = context.getBean(VcsOperator.class);
int latestFileVersion = 0;
try {
latestFileVersion = vcsOperator.getLatestFileVersion(fileName);
} catch (Exception e1) {
FineLoggerFactory.getLogger().error(e1.getMessage());
}
try {
if (jt.getEditingFILE() instanceof VcsCacheFileNodeFileProxy) {
vcsOperator.saveVersionFromCache(Constants.CURRENT_USERSNAME, fileName, StringUtils.EMPTY, latestFileVersion + 1);
context.getBean(FileVersionTablePanel.class).updateModel(1);
} else {
vcsOperator.saveVersion(Constants.CURRENT_USERSNAME, fileName, StringUtils.EMPTY, latestFileVersion + 1);
}
} catch (Exception e1) {
FineLoggerFactory.getLogger().error(e1.getMessage());
}
} }
}); });
return saveButton; return saveButton;
} }
public static String getEditingFilename() {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
String editingFilePath = jt.getEditingFILE().getPath();
//TODO 如果是cache里的文件,也会走到这里,这里是找到reportlets去掉的。万一刚好cache/reportlets会出问题
if (editingFilePath.startsWith(ProjectConstants.REPORTLETS_NAME)) {
editingFilePath = editingFilePath.replaceFirst(ProjectConstants.REPORTLETS_NAME, StringUtils.EMPTY);
} else if (editingFilePath.startsWith(Constants.VCS_CACHE_DIR)) {
editingFilePath = editingFilePath.replaceFirst(Constants.VCS_CACHE_DIR, StringUtils.EMPTY);
}
//TODO refactor 考虑直接用reportlets/xxx/x/x/x/x/x// or /xx/x/x/x/x/x
if (editingFilePath.startsWith("/")) {
editingFilePath = editingFilePath.substring(1);
}
return editingFilePath;
}
private UIButton createUndoButton() { private UIButton createUndoButton() {
undo = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/undo.png")); undo = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/undo.png"));
undo.setToolTipText(KeySetUtils.UNDO.getMenuKeySetName()); undo.setToolTipText(KeySetUtils.UNDO.getMenuKeySetName());

Loading…
Cancel
Save