diff --git a/designer-base/src/main/java/com/fr/design/actions/UpdateAction.java b/designer-base/src/main/java/com/fr/design/actions/UpdateAction.java index 5c12ff29c..048f23337 100644 --- a/designer-base/src/main/java/com/fr/design/actions/UpdateAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/UpdateAction.java @@ -345,6 +345,17 @@ public abstract class UpdateAction extends ShortCut implements Action { return (JComponent) object; } + public JComponent createToolBarComponentByName(String componentName) { + Object object = this.getValue(componentName); + if (!(object instanceof AbstractButton)) { + UIButton button = null; + button = new UIButton(); + object = initButton(button, componentName); + } + + return (JComponent) object; + } + protected JComponent initButton(UIButton button, String name) { // 添加一个名字作为自动化测试用 button.setName(getName()); diff --git a/designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java b/designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java index bc1445718..fdfdc31b5 100644 --- a/designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java @@ -25,9 +25,6 @@ import com.fr.esd.event.DsNameTarget; import com.fr.esd.event.StrategyEventsNotifier; import com.fr.file.TableDataConfig; -import com.fr.transaction.CallBackAdaptor; -import com.fr.transaction.Configurations; -import com.fr.transaction.WorkerFacade; import com.fr.report.LockItem; import javax.swing.KeyStroke; @@ -106,33 +103,17 @@ public class GlobalTableDataAction extends UpdateAction implements ResponseDataS globalTableDataDialog.setDoOKSucceed(false); return; } + globalTableDataPane.update(tableDataConfig); DesignTableDataManager.clearGlobalDs(); // 保存时 移除服务器数据集列名缓存 for (String name : tableDataConfig.getTableDatas().keySet()) { DesignTableDataManager.removeSelectedColumnNames(name); } - - Configurations.modify(new WorkerFacade(TableDataConfig.class) { - @Override - public void run() { - globalTableDataPane.update(tableDataConfig); - } - }.addCallBack(new CallBackAdaptor() { - @Override - public boolean beforeCommit() { - //如果更新失败,则不关闭对话框,也不写xml文件,并且将对话框定位在请重命名的那个对象页面 - return doWithDatasourceManager(tableDataConfig, globalTableDataPane, globalTableDataDialog); - } - - @Override - public void afterCommit() { - // 刷新共有数据集 - TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()); - fireDSChanged(globalTableDataPane.getDsChangedNameMap()); - // 关闭服务器数据集页面,为其解锁 - EditLockUtils.unlock(LockItem.SERVER_TABLE_DATA); - } - })); + // 刷新共有数据集 + TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()); + fireDSChanged(globalTableDataPane.getDsChangedNameMap()); + // 关闭服务器数据集页面,为其解锁 + EditLockUtils.unlock(LockItem.SERVER_TABLE_DATA); } @Override diff --git a/designer-base/src/main/java/com/fr/design/beans/ErrorMsgTextFieldAdapter.java b/designer-base/src/main/java/com/fr/design/beans/ErrorMsgTextFieldAdapter.java new file mode 100644 index 000000000..e2444a4ec --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/beans/ErrorMsgTextFieldAdapter.java @@ -0,0 +1,11 @@ +package com.fr.design.beans; + +import javax.swing.JComponent; + +public interface ErrorMsgTextFieldAdapter { + void setText(String str); + + String getText(); + + JComponent getErrorMsgTextField(); +} diff --git a/designer-base/src/main/java/com/fr/design/beans/UITextFieldAdapter.java b/designer-base/src/main/java/com/fr/design/beans/UITextFieldAdapter.java new file mode 100644 index 000000000..48fa6944f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/beans/UITextFieldAdapter.java @@ -0,0 +1,46 @@ +package com.fr.design.beans; + +import com.fr.design.gui.itextfield.UITextField; + +import javax.swing.JComponent; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +public class UITextFieldAdapter implements ErrorMsgTextFieldAdapter { + private final UITextField uiTextField = new UITextField(); + + public UITextFieldAdapter(){ + addDocumentListener(); + } + @Override + public void setText(String str) { + uiTextField.setText(str); + } + + @Override + public String getText() { + return uiTextField.getText(); + } + + public void addDocumentListener() { + uiTextField.getDocument().addDocumentListener(new DocumentListener() { + + public void changedUpdate(DocumentEvent e) { + uiTextField.setToolTipText(uiTextField.getText()); + } + + public void insertUpdate(DocumentEvent e) { + uiTextField.setToolTipText(uiTextField.getText()); + } + + public void removeUpdate(DocumentEvent e) { + uiTextField.setToolTipText(uiTextField.getText()); + } + }); + } + + @Override + public JComponent getErrorMsgTextField() { + return uiTextField; + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/border/UITitledBorder.java b/designer-base/src/main/java/com/fr/design/border/UITitledBorder.java index 3987844cf..875ef0083 100644 --- a/designer-base/src/main/java/com/fr/design/border/UITitledBorder.java +++ b/designer-base/src/main/java/com/fr/design/border/UITitledBorder.java @@ -22,24 +22,7 @@ public class UITitledBorder extends TitledBorder { } private UITitledBorder(String title) { - super( - BorderFactory.createCompoundBorder( - BorderFactory.createEmptyBorder( - 0, - 0, - 5, - 0), - new UIRoundedBorder( - UIConstants.TITLED_BORDER_COLOR, - 1, - 10) - ), - title, - TitledBorder.LEADING, - TitledBorder.TOP, - null, - new Color(1, 159, 222) - ); + this(title, 10); } /** diff --git a/designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java b/designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java new file mode 100644 index 000000000..c46143e1e --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java @@ -0,0 +1,32 @@ +package com.fr.design.border; + +import com.fr.design.constants.UIConstants; + +import javax.swing.BorderFactory; +import javax.swing.border.TitledBorder; +import java.awt.Color; + +public class UITitledMatteBorder extends TitledBorder { + public static UITitledMatteBorder createTitledTopBorder(String title, Color color) { + return new UITitledMatteBorder(title, 1, 0, 0, 0, color); + } + + public static UITitledMatteBorder createTitledBorder(String title, Color color) { + return new UITitledMatteBorder(title, 1, 1, 1, 1, color); + } + + public static UITitledMatteBorder createTitledBorder(String title, int top, int left, int bottom, int right, Color color) { + return new UITitledMatteBorder(title, top, left, bottom, right, color); + } + + private UITitledMatteBorder(String title, int top, int left, int bottom, int right, Color color) { + super( + BorderFactory.createMatteBorder(top, left, bottom, right, UIConstants.TITLED_BORDER_COLOR), + title, + TitledBorder.LEADING, + TitledBorder.TOP, + null, + color + ); + } +} diff --git a/designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java b/designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java index 393f217ce..355dca62d 100644 --- a/designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java @@ -6,6 +6,9 @@ import com.fr.base.Style; import com.fr.general.IOUtils; import javax.swing.JPanel; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; @@ -40,10 +43,22 @@ public class CellStylePreviewPane extends JPanel { @Override public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; - int resolution = ScreenResolution.getScreenResolution(); + g.clearRect(0, 0, getWidth(), getHeight()); - int width = getWidth(); - int height = getHeight(); + paintTransparentBackground(g2d, style); + + paintCellStyle(g2d, style); + } + + private void paintTransparentBackground(Graphics2D g2d, Style style) { + Color fontColor = style.getFRFont().getForeground(); + float g = fontColor.getRed() * 0.299F + fontColor.getGreen() * 0.587F * fontColor.getBlue() * 0.114F; + float alpha = 1.0F; + if (g < 50) { + alpha = 0.2F; + } else if (g < 160){ + alpha = 0.5F; + } float scaleWidth = 1.0F * getWidth() / transparentBackgroundWidth; float scaleHeight = 1.0F * getHeight() / transparentBackgroundHeight; @@ -54,7 +69,18 @@ public class CellStylePreviewPane extends JPanel { } else { scaleHeight = scaleWidth = maxScale; } + + Composite oldComposite = g2d.getComposite(); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); g2d.drawImage(transparentBackgroundImage, 0, 0, (int) (transparentBackgroundWidth * scaleWidth), (int) (transparentBackgroundHeight * scaleHeight), null); + g2d.setComposite(oldComposite); + } + + private void paintCellStyle(Graphics2D g2d, Style style) { + int resolution = ScreenResolution.getScreenResolution(); + + int width = getWidth(); + int height = getHeight(); if (style == Style.DEFAULT_STYLE) { // 如果是默认的style,就只写"Report"上去 diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java index 8972821b4..32bd070d9 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java @@ -1,6 +1,8 @@ package com.fr.design.data.datapane; import com.fr.base.TableData; +import com.fr.base.TableDataBean; +import com.fr.config.RemoteConfigEvent; import com.fr.data.TableDataSource; import com.fr.data.api.StoreProcedureAssist; import com.fr.data.impl.storeproc.StoreProcedure; @@ -12,22 +14,26 @@ import com.fr.design.gui.controlpane.JListControlPane; import com.fr.design.gui.controlpane.NameableCreator; import com.fr.design.gui.ilist.ListModelElement; import com.fr.design.i18n.Toolkit; +import com.fr.event.EventDispatcher; import com.fr.file.ProcedureConfig; import com.fr.file.TableDataConfig; +import com.fr.file.TableDataOperator; import com.fr.general.ComparatorUtils; import com.fr.general.NameObject; +import com.fr.log.FineLoggerFactory; import com.fr.stable.ArrayUtils; import com.fr.stable.Nameable; import com.fr.stable.StringUtils; import com.fr.stable.core.PropertyChangeAdapter; +import com.fr.third.org.apache.commons.collections4.MapUtils; +import com.fr.workspace.WorkContext; import javax.swing.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -231,15 +237,25 @@ public class TableDataPaneListPane extends JListControlPane implements TableData @Override public void update(TableDataConfig tableDataConfig) { - tableDataConfig.removeAllTableData(); - ProcedureConfig.getInstance().removeAllProcedure(); Nameable[] tableDataArray = this.update(); - Map tableDataMap = new LinkedHashMap(); + List tableDataBeans = new ArrayList<>(); + Map map = MapUtils.invertMap(getDsNameChangedMap()); for (int i = 0; i < tableDataArray.length; i++) { NameObject nameObject = (NameObject) tableDataArray[i]; - tableDataMap.put(nameObject.getName(), (TableData) nameObject.getObject()); + String oldName = map.get(nameObject.getName()); + if (oldName == null) { + oldName = StringUtils.EMPTY; + } + tableDataBeans.add(new TableDataBean(nameObject.getName(), oldName, (TableData) nameObject.getObject())); + } + try { + WorkContext.getCurrent().get(TableDataOperator.class).saveTableData(tableDataBeans); + if (!WorkContext.getCurrent().isLocal()) { + EventDispatcher.fire(RemoteConfigEvent.EDIT, TableDataConfig.class.getSimpleName()); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); } - tableDataConfig.setTableDatas(tableDataMap); } @Override diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java index 5ed53cef4..3b5aebed9 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java @@ -5,20 +5,13 @@ import com.fr.data.impl.AbstractDatabaseConnection; import com.fr.data.impl.Connection; import com.fr.data.impl.NameDatabaseConnection; import com.fr.design.DesignerEnvManager; -import com.fr.design.actions.server.ConnectionListAction; -import com.fr.design.dialog.BasicDialog; -import com.fr.design.dialog.DialogActionAdapter; import com.fr.design.editlock.ConnectionLockChangeChecker; import com.fr.design.editlock.EditLockUtils; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UILockButton; -import com.fr.design.mainframe.DesignerContext; import com.fr.file.ConnectionConfig; import com.fr.general.ComparatorUtils; import com.fr.stable.StringUtils; -import com.fr.transaction.CallBackAdaptor; -import com.fr.transaction.Configurations; -import com.fr.transaction.WorkerFacade; import com.fr.workspace.WorkContext; import com.fr.workspace.server.connection.DBConnectAuth; import com.fr.report.LockItem; @@ -133,48 +126,7 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel { return; } // 锁定成功,执行后续操作 - final ConnectionListPane connectionListPane = new ConnectionListPane(); - final ConnectionConfig connectionConfig = ConnectionConfig.getInstance(); - ConnectionConfig cloned = connectionConfig.mirror(); - connectionListPane.populate(cloned); - final BasicDialog connectionListDialog = connectionListPane.showLargeWindow( - SwingUtilities.getWindowAncestor(ConnectionComboBoxPanel.this), null); - connectionListDialog.addDialogActionListener(new DialogActionAdapter() { - public void doOk() { - if (!connectionListPane.isNamePermitted()) { - connectionListDialog.setDoOKSucceed(false); - return; - } - Configurations.modify(new WorkerFacade(ConnectionConfig.class) { - @Override - public void run() { - connectionListPane.update(connectionConfig); - } - }.addCallBack(new CallBackAdaptor() { - @Override - public boolean beforeCommit() { - //如果更新失败,则不关闭对话框,也不写xml文件,并且将对话框定位在请重命名的那个对象页面 - return ConnectionListAction.doWithDatasourceManager(connectionConfig, connectionListPane, connectionListDialog); - } - - @Override - public void afterCommit() { - DesignerContext.getDesignerBean("databasename").refreshBeanElement(); - // 关闭定义数据连接页面,为其解锁 - EditLockUtils.unlock(LockItem.CONNECTION); - } - })); - - } - - @Override - public void doCancel() { - // 关闭定义数据连接页面,为其解锁 - super.doCancel(); - EditLockUtils.unlock(LockItem.CONNECTION); - } - }); - connectionListDialog.setVisible(true); + ConnectionListPane.showDialog(SwingUtilities.getWindowAncestor(ConnectionComboBoxPanel.this)); refreshItems(); } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListDialogActionAdapter.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListDialogActionAdapter.java new file mode 100644 index 000000000..2428c9a00 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListDialogActionAdapter.java @@ -0,0 +1,48 @@ +package com.fr.design.data.datapane.connect; + +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.editlock.EditLockUtils; +import com.fr.design.mainframe.DesignerContext; +import com.fr.file.ConnectionConfig; +import com.fr.report.LockItem; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2021/9/8 + */ +public class ConnectionListDialogActionAdapter extends DialogActionAdapter { + + private final ConnectionManagerPane connectionManagerPane; + private final BasicDialog connectionListDialog; + private final ConnectionConfig connectionConfig; + + public ConnectionListDialogActionAdapter(ConnectionManagerPane connectionManagerPane, + BasicDialog connectionListDialog, + ConnectionConfig connectionConfig) { + this.connectionManagerPane = connectionManagerPane; + this.connectionListDialog = connectionListDialog; + this.connectionConfig = connectionConfig; + } + + @Override + public void doOk() { + if (!connectionManagerPane.isNamePermitted()) { + connectionListDialog.setDoOKSucceed(false); + return; + } + connectionManagerPane.update(connectionConfig); + DesignerContext.getDesignerBean("databasename").refreshBeanElement(); + // 关闭定义数据连接页面,为其解锁 + EditLockUtils.unlock(LockItem.CONNECTION); + + } + + @Override + public void doCancel() { + // 关闭定义数据连接页面,为其解锁 + super.doCancel(); + EditLockUtils.unlock(LockItem.CONNECTION); + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index 1e3f96a98..018aa8f4c 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -1,23 +1,32 @@ package com.fr.design.data.datapane.connect; +import com.fr.config.RemoteConfigEvent; import com.fr.data.impl.Connection; +import com.fr.data.impl.ConnectionBean; import com.fr.data.impl.JDBCDatabaseConnection; import com.fr.data.impl.JNDIDatabaseConnection; import com.fr.design.ExtraDesignClassManager; +import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.fun.ConnectionProvider; import com.fr.design.gui.controlpane.JListControlPane; import com.fr.design.gui.controlpane.NameObjectCreator; import com.fr.design.gui.controlpane.NameableCreator; import com.fr.design.i18n.Toolkit; +import com.fr.event.EventDispatcher; import com.fr.file.ConnectionConfig; import com.fr.general.ComparatorUtils; import com.fr.general.NameObject; +import com.fr.log.FineLoggerFactory; import com.fr.stable.ArrayUtils; import com.fr.stable.Nameable; import com.fr.stable.StringUtils; import com.fr.stable.core.PropertyChangeAdapter; +import com.fr.third.org.apache.commons.collections4.MapUtils; +import com.fr.workspace.WorkContext; +import com.fr.file.ConnectionOperator; +import java.awt.Window; import javax.swing.*; import java.util.ArrayList; import java.util.Arrays; @@ -67,8 +76,19 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh protected void rename(String oldName, String newName) { - renameMap.remove(selectedName); - renameMap.put(selectedName, newName); + //如果a改成了b,b又被改成了c,就认为是a改成了c + for (Map.Entry entry : renameMap.entrySet()) { + if (StringUtils.equals(oldName, entry.getValue())) { + oldName = entry.getKey(); + break; + } + } + if (StringUtils.equals(oldName, newName)) { + //a -> b;b -> a,说明没改 + renameMap.remove(oldName); + } else { + renameMap.put(oldName, newName); + } } /** @@ -149,14 +169,42 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh public void update(ConnectionConfig connectionConfig) { // Nameable[]居然不能强转成NameObject[],一定要这么写... Nameable[] res = this.update(); - NameObject[] res_array = new NameObject[res.length]; - java.util.Arrays.asList(res).toArray(res_array); + List connectionBeans = new ArrayList<>(); + Map map = MapUtils.invertMap(getRenameMap()); + for (int i = 0; i < res.length; i++) { + NameObject nameObject = (NameObject) res[i]; + String oldName = map.get(nameObject.getName()); + if (oldName == null) { + oldName = StringUtils.EMPTY; + } + connectionBeans.add(new ConnectionBean(nameObject.getName(), oldName, (Connection) nameObject.getObject())); + } + try { + WorkContext.getCurrent().get(ConnectionOperator.class).saveConnection(connectionBeans); + if (!WorkContext.getCurrent().isLocal()) { + EventDispatcher.fire(RemoteConfigEvent.EDIT, ConnectionConfig.class.getSimpleName()); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } - connectionConfig.removeAllConnection(); + public static void showDialog(Window parent) { + final ConnectionConfig connectionConfig = ConnectionConfig.getInstance(); + final ConnectionManagerPane connectionManagerPane = new ConnectionManagerPane() { + @Override + public void complete() { + ConnectionConfig cloned = connectionConfig.mirror(); + populate(cloned); + } - for (int i = 0; i < res_array.length; i++) { - NameObject nameObject = res_array[i]; - connectionConfig.addConnection(nameObject.getName(), (Connection) nameObject.getObject()); - } + @Override + protected void renameConnection(String oldName, String newName) { + connectionConfig.renameConnection(oldName, newName); + } + }; + final BasicDialog connectionListDialog = connectionManagerPane.showLargeWindow(parent, null); + connectionListDialog.addDialogActionListener(new ConnectionListDialogActionAdapter(connectionManagerPane, connectionListDialog, connectionConfig)); + connectionListDialog.setVisible(true); } } diff --git a/designer-base/src/main/java/com/fr/design/dialog/UIDialog.java b/designer-base/src/main/java/com/fr/design/dialog/UIDialog.java index dd3ddab3b..c15812357 100644 --- a/designer-base/src/main/java/com/fr/design/dialog/UIDialog.java +++ b/designer-base/src/main/java/com/fr/design/dialog/UIDialog.java @@ -175,7 +175,11 @@ public abstract class UIDialog extends JDialog { try { checkValid(); } catch (Exception exp) { - FineJOptionPane.showMessageDialog(this, exp.getMessage()); + FineJOptionPane.showMessageDialog( + this, + exp.getMessage(), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + JOptionPane.WARNING_MESSAGE); return; } diff --git a/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java b/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java index 6c3323600..b7a564713 100644 --- a/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java +++ b/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java @@ -4,6 +4,7 @@ package com.fr.design.file; import com.fr.base.BaseUtils; import com.fr.base.GraphHelper; import com.fr.base.vcs.DesignerMode; +import com.fr.design.base.mode.DesignModeContext; import com.fr.design.constants.UIConstants; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.imenu.UIMenuItem; @@ -763,7 +764,7 @@ public class MutilTempalteTabPane extends JComponent { /** * 关闭掉一个模板之后激活新的待显示模板 */ - private void activePrevTemplateAfterClose() { + public void activePrevTemplateAfterClose() { if (openedTemplate.isEmpty()) { //新建并激活模板 DesignerContext.getDesignerFrame().addAndActivateJTemplate(); diff --git a/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java b/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java index 608e8e684..447421a41 100644 --- a/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java +++ b/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java @@ -655,7 +655,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { FormulaPane.this, formulaValidMessage + ".", com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), - JOptionPane.INFORMATION_MESSAGE); + JOptionPane.WARNING_MESSAGE); } }; diff --git a/designer-base/src/main/java/com/fr/design/fun/RegPaneProvider.java b/designer-base/src/main/java/com/fr/design/fun/RegPaneProvider.java new file mode 100644 index 000000000..26fe62b5e --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/fun/RegPaneProvider.java @@ -0,0 +1,11 @@ +package com.fr.design.fun; + +import com.fr.design.gui.frpane.RegFieldPane; +import com.fr.stable.fun.mark.Immutable; + +public interface RegPaneProvider extends Immutable { + int CURRENT_LEVEL = 1; + String XML_TAG = "RegPaneProvider"; + + RegFieldPane createRegPane(); +} diff --git a/designer-base/src/main/java/com/fr/design/fun/TextFieldAdapterProvider.java b/designer-base/src/main/java/com/fr/design/fun/TextFieldAdapterProvider.java new file mode 100644 index 000000000..2c7b7dcc6 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/fun/TextFieldAdapterProvider.java @@ -0,0 +1,11 @@ +package com.fr.design.fun; + +import com.fr.design.beans.ErrorMsgTextFieldAdapter; +import com.fr.stable.fun.mark.Immutable; + +public interface TextFieldAdapterProvider extends Immutable { + String XML_TAG = "ErrorMesPaneWrapperProvider"; + int CURRENT_LEVEL = 1; + + ErrorMsgTextFieldAdapter createTextFieldAdapter(); +} diff --git a/designer-base/src/main/java/com/fr/design/fun/impl/AbstractRegPaneProvider.java b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractRegPaneProvider.java new file mode 100644 index 000000000..98185f2a5 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractRegPaneProvider.java @@ -0,0 +1,22 @@ +package com.fr.design.fun.impl; + +import com.fr.design.fun.RegPaneProvider; +import com.fr.stable.fun.mark.API; + +/** + * @author Joe + * 2021/10/8 15:19 + */ +@API(level = RegPaneProvider.CURRENT_LEVEL) +public abstract class AbstractRegPaneProvider implements RegPaneProvider { + + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + @Override + public int layerIndex() { + return DEFAULT_LAYER_INDEX; + } +} diff --git a/designer-base/src/main/java/com/fr/design/fun/impl/AbstractTextFieldAdapterProvider.java b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractTextFieldAdapterProvider.java new file mode 100644 index 000000000..bc0836eb4 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractTextFieldAdapterProvider.java @@ -0,0 +1,22 @@ +package com.fr.design.fun.impl; + +import com.fr.design.fun.TextFieldAdapterProvider; +import com.fr.stable.fun.mark.API; + +/** + * @author Joe + * 2021/10/8 15:17 + */ +@API(level = TextFieldAdapterProvider.CURRENT_LEVEL) +public abstract class AbstractTextFieldAdapterProvider implements TextFieldAdapterProvider { + + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + @Override + public int layerIndex() { + return DEFAULT_LAYER_INDEX; + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/chart/ChartEditPaneProvider.java b/designer-base/src/main/java/com/fr/design/gui/chart/ChartEditPaneProvider.java index 300380036..0a3684ba3 100644 --- a/designer-base/src/main/java/com/fr/design/gui/chart/ChartEditPaneProvider.java +++ b/designer-base/src/main/java/com/fr/design/gui/chart/ChartEditPaneProvider.java @@ -16,4 +16,7 @@ public interface ChartEditPaneProvider { default void removeChartEditPaneActionListener(ChartEditPaneActionListener l) { } + default void resetLastChartCollection() { + } + } diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/RegFieldPane.java b/designer-base/src/main/java/com/fr/design/gui/frpane/RegFieldPane.java index 5d37fb4a9..38e33514b 100644 --- a/designer-base/src/main/java/com/fr/design/gui/frpane/RegFieldPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/RegFieldPane.java @@ -1,21 +1,25 @@ package com.fr.design.gui.frpane; +import com.fr.design.ExtraDesignClassManager; +import com.fr.design.beans.ErrorMsgTextFieldAdapter; +import com.fr.design.beans.UITextFieldAdapter; import com.fr.design.constants.LayoutConstants; import com.fr.design.designer.IntervalConstants; import com.fr.design.dialog.BasicPane; +import com.fr.design.fun.TextFieldAdapterProvider; import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.itextfield.UITextField; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; import com.fr.form.ui.TextEditor; import com.fr.form.ui.reg.NoneReg; import com.fr.form.ui.reg.RegExp; +import com.fr.log.FineLoggerFactory; - -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import java.awt.*; +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; /** * Created by kerry on 2017/9/4. @@ -23,7 +27,7 @@ import java.awt.*; public class RegFieldPane extends RegPane { protected RegErrorMsgPane regErrorMsgPane; - public RegFieldPane(){ + public RegFieldPane() { this(ALL_REG_TYPE); } @@ -39,8 +43,8 @@ public class RegFieldPane extends RegPane { @Override public void regChangeAction() { - RegExp regExp = (RegExp)getRegComboBox().getSelectedItem(); - if(regExp instanceof NoneReg){ + RegExp regExp = (RegExp) getRegComboBox().getSelectedItem(); + if (regExp instanceof NoneReg) { regErrorMsgPane.setVisible(false); return; } @@ -67,33 +71,35 @@ public class RegFieldPane extends RegPane { } private static class RegErrorMsgPane extends BasicPane { - private UITextField regErrorMsgField; + private ErrorMsgTextFieldAdapter errorMsgTextFieldAdapter; public RegErrorMsgPane() { + initRegErrorMsgField(); + setStyle(); + } + + private void setStyle() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); this.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L6, IntervalConstants.INTERVAL_L5, 0, 0)); - initRegErrorMsgField(); UILabel tipLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Error_Tip")); tipLabel.setPreferredSize(new Dimension(60, 20)); - JPanel panel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{tipLabel, regErrorMsgField}}, TableLayoutHelper.FILL_LASTCOLUMN, 10, LayoutConstants.VGAP_MEDIUM); + JPanel panel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{tipLabel, errorMsgTextFieldAdapter.getErrorMsgTextField()}}, TableLayoutHelper.FILL_LASTCOLUMN, 10, LayoutConstants.VGAP_MEDIUM); this.add(panel); } private void initRegErrorMsgField() { - regErrorMsgField = new UITextField(); - regErrorMsgField.getDocument().addDocumentListener(new DocumentListener() { - public void changedUpdate(DocumentEvent e) { - regErrorMsgField.setToolTipText(regErrorMsgField.getText()); - } - - public void insertUpdate(DocumentEvent e) { - regErrorMsgField.setToolTipText(regErrorMsgField.getText()); - } + TextFieldAdapterProvider provider = ExtraDesignClassManager.getInstance().getSingle(TextFieldAdapterProvider.XML_TAG); + if (provider == null) { + errorMsgTextFieldAdapter = new UITextFieldAdapter(); + return; + } + try { + errorMsgTextFieldAdapter = provider.createTextFieldAdapter(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + errorMsgTextFieldAdapter = new UITextFieldAdapter(); - public void removeUpdate(DocumentEvent e) { - regErrorMsgField.setToolTipText(regErrorMsgField.getText()); - } - }); + } } @Override @@ -102,11 +108,11 @@ public class RegFieldPane extends RegPane { } public void populate(TextEditor textEditor) { - regErrorMsgField.setText(textEditor.getRegErrorMessage()); + errorMsgTextFieldAdapter.setText(textEditor.getRegErrorMessage()); } public void update(TextEditor textEditor) { - textEditor.setRegErrorMessage(regErrorMsgField.getText()); + textEditor.setRegErrorMessage(errorMsgTextFieldAdapter.getText()); } } diff --git a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java index 22f6cb246..4a722fc50 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java +++ b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java @@ -73,6 +73,12 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver textField.setValue(defaultValue); } + public UISpinner(double minValue, double maxValue, double dierta, double defaultValue, boolean fillNegativeNumber) { + init(minValue, maxValue, dierta); + textField.setValue(defaultValue); + textField.canFillNegativeNumber(fillNegativeNumber); + } + protected void init(double minValue, double maxValue, double dierta) { this.minValue = minValue; this.maxValue = maxValue; diff --git a/designer-base/src/main/java/com/fr/design/gui/style/AlignmentPane.java b/designer-base/src/main/java/com/fr/design/gui/style/AlignmentPane.java index b188cb5aa..eb72db81c 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/AlignmentPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/style/AlignmentPane.java @@ -17,6 +17,7 @@ import com.fr.design.gui.ibutton.UIButtonGroup; import com.fr.design.gui.icombobox.UIComboBox; 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.TableLayout; import com.fr.design.layout.TableLayoutHelper; @@ -56,11 +57,11 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO private static final int GAP = 23; private static final int VERGAP = 3; private static final Dimension SPINNER_DIMENSION = new Dimension(75, 20); - private static final String[] TEXT = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Wrap_Text"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Single_Line"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Single_Line(Adjust_Font)"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Multi_Line(Adjust_Font)")}; + private static final String[] TEXT = {Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Wrap_Text"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Single_Line"), + Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Single_Line(Adjust_Font)"), Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Multi_Line(Adjust_Font)")}; - private static final String[] LAYOUT = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Default"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Titled"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Extend"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Adjust")}; + private static final String[] LAYOUT = {Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Default"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Titled"), + Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Extend"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Adjust")}; private JPanel hPaneContainer; private JPanel vPaneContainer; @@ -103,8 +104,8 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO {IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/defaultAlignment.png"), IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/defaultAlignment_white.png")}}; Integer[] hAlignment = new Integer[]{Constants.LEFT, Constants.CENTER, Constants.RIGHT, Integer.valueOf(Constants.DISTRIBUTED), Constants.NULL}; hAlignmentPane = new UIButtonGroup<>(hAlignmentIconArray, hAlignment); - hAlignmentPane.setAllToolTips(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Left"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Center"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Right"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Distributed"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_DEFAULT")}); + hAlignmentPane.setAllToolTips(new String[]{Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Left"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Center"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Right"), + Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Distributed"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_DEFAULT")}); hPaneContainer = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); vPaneContainer = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); @@ -113,7 +114,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO {IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/v_down_normal.png"), IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/v_down_normal_white.png")}}; Integer[] vAlignment = new Integer[]{Constants.TOP, Constants.CENTER, Constants.BOTTOM}; vAlignmentPane = new UIButtonGroup<>(vAlignmentIconArray, vAlignment); - vAlignmentPane.setAllToolTips(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Top"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Center"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Bottom")}); + vAlignmentPane.setAllToolTips(new String[]{Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Top"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Center"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Bottom")}); initOtherComponent(); initAllNames(); @@ -175,7 +176,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO private void initTextRotationCombox() { ArrayList selectOption = new ArrayList<>(); - selectOption.add(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Custom_Angle")); + selectOption.add(Toolkit.i18nText("Fine-Design_Basic_Custom_Angle")); VerticalTextProcessor processor = ExtraClassManager.getInstance().getSingle(VerticalTextProcessor.XML_TAG, DefaultVerticalTextProcessor.class); selectOption.addAll(Arrays.asList(processor.getComboxOption())); @@ -183,25 +184,25 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO } private void initAllNames() { - hAlignmentPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal")); - vAlignmentPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical")); - imageLayoutComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Image_Layout")); - textComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style")); - textRotationComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation")); - rotationPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation")); - leftIndentSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Left_Indent")); - rightIndentSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Right_Indent")); - spaceBeforeSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_Before")); - spaceAfterSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_After")); - lineSpaceSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing")); + hAlignmentPane.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal")); + vAlignmentPane.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical")); + imageLayoutComboBox.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Image_Layout")); + textComboBox.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style")); + textRotationComboBox.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation")); + rotationPane.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation")); + leftIndentSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Left_Indent")); + rightIndentSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Right_Indent")); + spaceBeforeSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_Before")); + spaceAfterSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_After")); + lineSpaceSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing")); } private JPanel createPane() { JPanel jp1 = new JPanel(new BorderLayout()); basicPane = new JPanel(); seniorPane = new JPanel(); - basicPane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Basic"), 290, 24, basicPane()); - seniorPane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Advanced"), 290, 24, seniorPane()); + basicPane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Basic"), 290, 24, basicPane()); + seniorPane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Basic_Advanced"), 290, 24, seniorPane()); jp1.add(basicPane, BorderLayout.NORTH); jp1.add(seniorPane, BorderLayout.CENTER); @@ -212,13 +213,13 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO private JPanel basicPane() { double f = TableLayout.FILL; double p = TableLayout.PREFERRED; - UILabel horizontalLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal") + " ", SwingConstants.LEFT); + UILabel horizontalLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal") + " ", SwingConstants.LEFT); UIComponentUtils.setLineWrap(horizontalLabel); Component[][] components = new Component[][]{ new Component[]{null, null}, new Component[]{horizontalLabel, hPaneContainer}, new Component[]{null, null}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical") + " ", SwingConstants.RIGHT), vPaneContainer}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical") + " ", SwingConstants.RIGHT), vPaneContainer}, new Component[]{null, null} }; double[] rowSize = {p, p, p, p, p, p}; @@ -233,11 +234,11 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO double p = TableLayout.PREFERRED; Component[][] components = new Component[][]{ new Component[]{null, null}, - new Component[]{new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Image_Layout")) + " ", SwingConstants.LEFT), imageLayoutComboBox}, + new Component[]{new UILabel((Toolkit.i18nText("Fine-Design_Basic_Image_Layout")) + " ", SwingConstants.LEFT), imageLayoutComboBox}, new Component[]{null, null}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style") + " ", SwingConstants.LEFT), textComboBox}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style") + " ", SwingConstants.LEFT), textComboBox}, new Component[]{null, null}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation") + " ", SwingConstants.LEFT), textRotationComboBox}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation") + " ", SwingConstants.LEFT), textRotationComboBox}, new Component[]{null, rotationBarCC}, new Component[]{null, null}, }; @@ -261,23 +262,23 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO lineSpaceSpinner.setPreferredSize(SPINNER_DIMENSION); JPanel indentationPane = new JPanel(new BorderLayout()); - indentationPane.add(new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Indentation")), SwingConstants.LEFT)); + indentationPane.add(new UILabel((Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Indentation")), SwingConstants.LEFT)); indentationPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, GAP)); JPanel partSpacingPane = new JPanel(new BorderLayout()); - partSpacingPane.add(new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Part_Spacing")), SwingConstants.LEFT)); + partSpacingPane.add(new UILabel((Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Part_Spacing")), SwingConstants.LEFT)); partSpacingPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, GAP)); JPanel spacingPane = new JPanel(new BorderLayout()); - spacingPane.add(new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Spacing")), SwingConstants.LEFT)); + spacingPane.add(new UILabel((Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing")), SwingConstants.LEFT)); spacingPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, GAP)); Component[][] components = new Component[][]{ new Component[]{null, null, null}, new Component[]{indentationPane, creatSpinnerPane(leftIndentSpinner), creatSpinnerPane(rightIndentSpinner)}, - new Component[]{null, new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Left")), SwingConstants.CENTER), new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Right")), SwingConstants.CENTER)}, + new Component[]{null, new UILabel((Toolkit.i18nText("Fine-Design_Report_Left")), SwingConstants.CENTER), new UILabel((Toolkit.i18nText("Fine-Design_Basic_Right")), SwingConstants.CENTER)}, new Component[]{null, null, null}, new Component[]{null, null, null}, new Component[]{partSpacingPane, creatSpinnerPane(spaceBeforeSpinner), creatSpinnerPane(spaceAfterSpinner)}, - new Component[]{null, new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Front")), SwingConstants.CENTER), new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Behind")), SwingConstants.CENTER)}, + new Component[]{null, new UILabel((Toolkit.i18nText("Fine-Design_Basic_Front")), SwingConstants.CENTER), new UILabel((Toolkit.i18nText("Fine-Design_Basic_Behind")), SwingConstants.CENTER)}, new Component[]{null, null, null}, new Component[]{null, null, null}, new Component[]{spacingPane, creatSpinnerPane(lineSpaceSpinner), null}, @@ -300,7 +301,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO * @return 标题 */ public String title4PopupWindow() { - return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Alignment"); + return Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Alignment"); } /** @@ -363,18 +364,18 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO return null; } - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal"))) { Integer h = this.hAlignmentPane.getSelectedItem(); style = style.deriveHorizontalAlignment(h == null ? -1 : h); } - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical"))) { Integer vAlign = this.vAlignmentPane.getSelectedItem(); if (vAlign != null) { style = style.deriveVerticalAlignment(vAlign); } } - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style"))) { if (ComparatorUtils.equals(this.textComboBox.getSelectedItem(), TEXT[0])) { style = style.deriveTextStyle(Style.TEXTSTYLE_WRAPTEXT); } else if (ComparatorUtils.equals(this.textComboBox.getSelectedItem(), TEXT[1])) { @@ -394,7 +395,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO private Style updateImageLayout(Style style) { - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Image_Layout"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Image_Layout"))) { if (ComparatorUtils.equals(this.imageLayoutComboBox.getSelectedItem(), LAYOUT[1])) { style = style.deriveImageLayout(Constants.IMAGE_TILED); } else if (ComparatorUtils.equals(this.imageLayoutComboBox.getSelectedItem(), LAYOUT[2])) { @@ -410,7 +411,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO private Style updateTextRotation(Style style) { - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"))) { if (this.textRotationComboBox.getSelectedIndex() != 0) { style = style.deriveVerticalText(Style.VERTICALTEXT); style = style.deriveRotation(0); @@ -424,21 +425,21 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO } private Style updateOther(Style style) { - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Left_Indent"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Left_Indent"))) { style = style.derivePaddingLeft(indentationUnitProcessor.paddingUnitGainFromSpinner((int) (this.leftIndentSpinner.getValue()))); } - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Right_Indent"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Right_Indent"))) { style = style.derivePaddingRight(indentationUnitProcessor.paddingUnitGainFromSpinner((int) (this.rightIndentSpinner.getValue()))); } //间距 - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_Before"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_Before"))) { style = style.deriveSpacingBefore((int) (this.spaceBeforeSpinner.getValue())); } - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_After"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_After"))) { style = style.deriveSpacingAfter((int) (this.spaceAfterSpinner.getValue())); } - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing"))) { style = style.deriveLineSpacing((int) (this.lineSpaceSpinner.getValue())); } return style; diff --git a/designer-base/src/main/java/com/fr/design/gui/style/TextFontTippedPane.java b/designer-base/src/main/java/com/fr/design/gui/style/TextFontTippedPane.java new file mode 100644 index 000000000..7f11b0d4b --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/style/TextFontTippedPane.java @@ -0,0 +1,86 @@ +package com.fr.design.gui.style; + +import com.fr.base.Style; +import com.fr.design.constants.LayoutConstants; +import com.fr.design.designer.IntervalConstants; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.theme.edit.ui.LabelUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; + + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/29 + */ +public class TextFontTippedPane extends AbstractBasicStylePane { + + private FRFontPane fontPane; + + public TextFontTippedPane(boolean showFormatTip) { + this.initializePane(showFormatTip); + } + + private void initializePane(boolean showFormatTip) { + setLayout(new BorderLayout()); + setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0)); + + fontPane = new FRFontPane(); + this.add(createLabeledPane(Toolkit.i18nText("Fine-Design_Form_FR_Font"), fontPane), BorderLayout.NORTH); + + if (showFormatTip) { + JPanel formatTipPane = createFormatTipPane(); + this.add(formatTipPane, BorderLayout.CENTER); + } + } + + private JPanel createLabeledPane(String text, JPanel panel) { + double f = TableLayout.FILL; + double p = TableLayout.PREFERRED; + double[] rowSize = { p }; + double[] columnSize = {p, f}; + + UILabel uiLabel = new UILabel(text); + JPanel uiLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + uiLabelPane.add(uiLabel, BorderLayout.NORTH); + + return TableLayoutHelper.createGapTableLayoutPane(new Component[][]{ + new Component[] { uiLabelPane, panel }, + }, rowSize, columnSize, LayoutConstants.VGAP_LARGE, LayoutConstants.VGAP_MEDIUM); + } + + private JPanel createFormatTipPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0)); + JTextArea formatMigratedTip = LabelUtils.createAutoWrapLabel(Toolkit.i18nText("Fine-Design_Report_Format_Style_Migrated_Tip"), new Color(153, 153, 153)); + + container.add(formatMigratedTip, BorderLayout.NORTH); + return container; + } + + @Override + public String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Report_Text"); + } + + @Override + public void populateBean(Style style) { + this.fontPane.populateBean(style); + } + + @Override + public Style update(Style style) { + return this.fontPane.update(style); + } +} + diff --git a/designer-base/src/main/java/com/fr/design/gui/style/TextFormatPane.java b/designer-base/src/main/java/com/fr/design/gui/style/TextFormatPane.java new file mode 100644 index 000000000..ae0a94799 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/style/TextFormatPane.java @@ -0,0 +1,483 @@ +package com.fr.design.gui.style; + +import com.fr.base.CoreDecimalFormat; +import com.fr.base.GraphHelper; +import com.fr.base.Style; +import com.fr.base.TextFormat; +import com.fr.data.core.FormatField; +import com.fr.data.core.FormatField.FormatContents; +import com.fr.design.border.UIRoundedBorder; +import com.fr.design.constants.LayoutConstants; +import com.fr.design.constants.UIConstants; +import com.fr.design.event.GlobalNameListener; +import com.fr.design.event.GlobalNameObserver; +import com.fr.design.event.UIObserverListener; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.icombobox.TextFontComboBox; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.icombobox.UIComboBoxRenderer; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.general.ComparatorUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.UIManager; +import javax.swing.border.Border; +import javax.swing.border.TitledBorder; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.math.RoundingMode; +import java.text.Format; +import java.text.SimpleDateFormat; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/29 + * 包含格式相关的设置 + */ +public class TextFormatPane extends AbstractBasicStylePane implements GlobalNameObserver { + private static final long serialVersionUID = 724330854437726751L; + + private static final int LABEL_X = 4; + private static final int LABEL_Y = 18; + private static final int LABEL_DELTA_WIDTH = 8; + private static final int LABEL_HEIGHT = 15; //标签背景的范围 + private static final int CURRENCY_FLAG_POINT = 6; + + private static final Integer[] TYPES = new Integer[]{ + FormatContents.NULL, FormatContents.NUMBER, + FormatContents.CURRENCY, FormatContents.PERCENT, + FormatContents.SCIENTIFIC, FormatContents.DATE, + FormatContents.TIME, FormatContents.TEXT}; + + private static final Integer[] DATE_TYPES = new Integer[]{FormatContents.NULL, FormatContents.DATE, FormatContents.TIME}; + + private Format format; + + private UIComboBox typeComboBox; + private TextFontComboBox textField; + private UILabel sampleLabel; + private JPanel contentPane; + private JPanel txtCenterPane; + private JPanel centerPane; + private JPanel optionPane; + private UICheckBox roundingBox; + private JPanel formatFontPane; + private boolean isRightFormat; + private boolean isDate = false; + private GlobalNameListener globalNameListener = null; + + /** + * Constructor. + */ + public TextFormatPane() { + this.initComponents(TYPES); + } + + protected UIComboBox getTypeComboBox() { + return typeComboBox; + } + + protected void initComponents(Integer[] types) { + this.setLayout(new BorderLayout(0, 4)); + initSampleLabel(); + contentPane = new JPanel(new BorderLayout(0, 4)) { + @Override + public Dimension getPreferredSize() { + return new Dimension(super.getPreferredSize().width, 65); + } + }; + typeComboBox = new UIComboBox(types); + UIComboBoxRenderer render = createComBoxRender(); + typeComboBox.setRenderer(render); + typeComboBox.addItemListener(itemListener); + typeComboBox.setGlobalName("typeComboBox"); + contentPane.add(sampleLabel, BorderLayout.NORTH); + + txtCenterPane = new JPanel(new BorderLayout()); + textField = new TextFontComboBox(); + textField.addItemListener(textFieldItemListener); + textField.setEditable(true); + textField.setGlobalName("textField"); + txtCenterPane.add(textField, BorderLayout.NORTH); + + contentPane.add(txtCenterPane, BorderLayout.CENTER); + + centerPane = new JPanel(new CardLayout()); + centerPane.add(new JPanel(), "hide"); + centerPane.setPreferredSize(new Dimension(0, 0)); + centerPane.add(contentPane, "show"); + + typeComboBox.setPreferredSize(new Dimension(155,20)); + JPanel typePane = new JPanel(new BorderLayout()); + typePane.add(typeComboBox, BorderLayout.CENTER); + typePane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); + + JPanel option = new JPanel(new BorderLayout()); + option.add(new UILabel(Toolkit.i18nText("Fine-Design_Report_Base_Option"), SwingConstants.LEFT), BorderLayout.WEST); + roundingBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_Base_Option_Half_Up")); + roundingBox.setBorder(BorderFactory.createEmptyBorder(0, 30, 0, 0)); + roundingBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + } + }); + roundingBox.setGlobalName("roundingBox"); + option.add(roundingBox, BorderLayout.CENTER); + optionPane = new JPanel(new CardLayout()); + optionPane.add(new JPanel(), "hide"); + optionPane.setPreferredSize(new Dimension(0, 0)); + optionPane.add(option, "show"); + + Component[][] components = getComponent(centerPane, typePane); + this.add(createContentPane(components), BorderLayout.CENTER); + } + + protected JPanel createContentPane (Component[][] components) { + double f = TableLayout.FILL; + double p = TableLayout.PREFERRED; + double[] rowSize = {p, p, p, p, p}; + double[] columnSize = {p, f}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}; + return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.VGAP_LARGE, LayoutConstants.VGAP_MEDIUM); + } + + + protected Component[][] getComponent (JPanel centerPane, JPanel typePane) { + return new Component[][]{ + new Component[]{null, null}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Report_Base_Format"), SwingConstants.LEFT), typePane}, + new Component[]{centerPane, null}, + new Component[]{optionPane, null}, + }; + } + + protected UIComboBoxRenderer createComBoxRender() { + return new UIComboBoxRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value instanceof Integer) { + label.setText(" " + FormatField.getInstance().getName((Integer) value)); + } + return label; + } + }; + } + + private void initSampleLabel() { + Border interBorder = new UIRoundedBorder(UIConstants.LINE_COLOR, 1, 4); + String title = Toolkit.i18nText("Fine-Design_Report_Base_StyleFormat_Sample"); + Border border = BorderFactory.createTitledBorder(interBorder, title, TitledBorder.LEFT, 0, null, UIConstants.LINE_COLOR); + sampleLabel = new UILabel(FormatField.getInstance().getFormatValue()) { + + @Override + public void paint(Graphics g) { + super.paint(g); + int width = getWidth(); + Color original = g.getColor(); + g.setColor(getBackground()); + g.fillRect(LABEL_X, LABEL_Y, width - LABEL_DELTA_WIDTH, LABEL_HEIGHT); + g.setColor(UIConstants.LINE_COLOR); + FontMetrics cellFM = g.getFontMetrics(); + int textWidth = cellFM.stringWidth(getText()); + GraphHelper.drawString(g, getText(), (width - textWidth) / 2, 26); + g.setColor(original); + } + }; + sampleLabel.setHorizontalAlignment(UILabel.CENTER); + sampleLabel.setBorder(border); + } + + + @Override + /** + * 得到合适的大小 + */ + public Dimension getPreferredSize() { + if (this.typeComboBox.getSelectedIndex() == FormatContents.NULL) { + return typeComboBox.getPreferredSize(); + } + return super.getPreferredSize(); + } + + /** + * 弹出框标题 + * + * @return 标题 + */ + public String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Report_Text"); + } + + /** + * Populate + */ + public void populateBean(Format format) { + this.format = format; + + if (format == null) { + this.typeComboBox.setSelectedIndex(FormatContents.NULL); + } else { + if (format instanceof CoreDecimalFormat) { + // check all value + String pattern = ((CoreDecimalFormat) format).toPattern(); + if (isCurrencyFormatStyle(pattern)) { + setPatternComboBoxAndList(FormatContents.CURRENCY, pattern); + } else if (pattern.indexOf("%") > 0) { + setPatternComboBoxAndList(FormatContents.PERCENT, pattern); + this.roundingBox.setSelected(((CoreDecimalFormat) format).getRoundingMode().equals(RoundingMode.HALF_UP)); + } else if (pattern.indexOf("E") > 0) { + setPatternComboBoxAndList(FormatContents.SCIENTIFIC, pattern); + } else { + setPatternComboBoxAndList(FormatContents.NUMBER, pattern); + } + } else if (format instanceof SimpleDateFormat) { // date and time + String pattern = ((SimpleDateFormat) format).toPattern(); + if (!isTimeType(pattern)) { + setPatternComboBoxAndList(FormatContents.DATE, pattern); + } else { + setPatternComboBoxAndList(FormatContents.TIME, pattern); + } + } else if (format instanceof TextFormat) { // Text + this.typeComboBox.setSelectedItem(FormatContents.TEXT); + } + } + } + + private boolean isCurrencyFormatStyle(String pattern) { + if (pattern.length() == 0) { + return false; + } + + if (pattern.charAt(0) == '¤' || pattern.charAt(0) == '$') { + return true; + } + + return pattern.length() > CURRENCY_FLAG_POINT && pattern.startsWith("#,##0;"); + } + + /** + * 判断是否是数组有模式 + * + * @param stringArray 字符串数组 + * @param pattern 格式 + * @return 是否是数组有模式 + */ + public static int isArrayContainPattern(String[] stringArray, String pattern) { + for (int i = 0; i < stringArray.length; i++) { + if (ComparatorUtils.equals(stringArray[i], pattern)) { + return i; + } + } + + return -1; + } + + private void setPatternComboBoxAndList(int formatStyle, String pattern) { + this.typeComboBox.setSelectedItem(formatStyle); + this.textField.setSelectedItem(pattern); + } + + private boolean isTimeType(String pattern) { + return pattern.matches(".*[Hhmsa].*"); + } + + /** + * update + */ + public Format update() { + String patternString = String.valueOf(textField.getSelectedItem()); + if (getFormatContents() == FormatContents.TEXT) { + return FormatField.getInstance().getFormat(getFormatContents(), patternString); + } + if (isRightFormat) { + if (StringUtils.isNotEmpty(patternString)) { + RoundingMode roundingMode = roundingBox.isSelected() ? RoundingMode.HALF_UP : RoundingMode.HALF_EVEN; + return FormatField.getInstance().getFormat(getFormatContents(), patternString, roundingMode); + } + } + return null; + } + + private int getFormatContents() { + return (Integer) typeComboBox.getSelectedItem(); + } + + /** + * Refresh preview label. + */ + private void refreshPreviewLabel() { + this.sampleLabel.setText(FormatField.getInstance().getFormatValue()); + this.sampleLabel.setForeground(UIManager.getColor("Label.foreground")); + try { + isRightFormat = true; + if (StringUtils.isEmpty(String.valueOf(textField.getSelectedItem()))) { + return; + } + this.sampleLabel.setText(FormatField.getInstance().getFormatValue(getFormatContents(), String.valueOf(textField.getSelectedItem()))); + } catch (Exception e) { + this.sampleLabel.setForeground(Color.red); + this.sampleLabel.setText(e.getMessage()); + isRightFormat = false; + } + } + + private boolean isTextOrNull() { + int contents = getFormatContents(); + return contents == FormatContents.TEXT || contents == FormatContents.NULL; + } + + /** + * Radio selection listener. + */ + ItemListener itemListener = new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + int contents = getFormatContents(); + String[] items = FormatField.getInstance().getFormatArray(contents, false); + CardLayout cardLayout = (CardLayout) centerPane.getLayout(); + + if (isTextOrNull()) { + centerPane.setPreferredSize(new Dimension(0, 0)); + cardLayout.show(centerPane, "hide"); + } else { + textField.removeAllItems(); + textField.setItemArray(items); + textField.setSelectedIndex(0); + centerPane.setPreferredSize(new Dimension(270, 65)); + cardLayout.show(centerPane, "show"); + } + CardLayout optionLayout = ((CardLayout) optionPane.getLayout()); + if (getFormatContents() == FormatContents.PERCENT) { + optionPane.setPreferredSize(new Dimension(100, 20)); + optionLayout.show(optionPane, "show"); + } else { + optionPane.setPreferredSize(new Dimension(0, 0)); + optionLayout.show(optionPane, "hide"); + roundingBox.setSelected(false); + } + } + + } + }; + + ItemListener textFieldItemListener = new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + refreshPreviewLabel(); + } + } + }; + + @Override + /** + * populate + */ + public void populateBean(Style style) { + this.populateBean(style.getFormat()); + } + + @Override + /** + * update + */ + public Style update(Style style) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), "textField") + || ComparatorUtils.equals(globalNameListener.getGlobalName(), "typeComboBox") + || ComparatorUtils.equals(globalNameListener.getGlobalName(), "roundingBox")) { + return style.deriveFormat(this.update()); + } + return style; + } + + /** + * 默认只显示百分比的编辑下拉. + */ + public void justUsePercentFormat() { + typeComboBox.setEnabled(false); + this.typeComboBox.setSelectedItem(FormatContents.PERCENT); + } + + public void setForDataSheet() { + Integer[] otherTypes = new Integer[]{FormatContents.NULL, FormatContents.NUMBER, FormatContents.CURRENCY, FormatContents.PERCENT, FormatContents.SCIENTIFIC,}; + this.typeComboBox = new UIComboBox(otherTypes); + UIComboBoxRenderer render = new UIComboBoxRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value instanceof Integer) { + label.setText(" " + FormatField.getInstance().getName((Integer) value)); + } + return label; + } + }; + typeComboBox.setRenderer(render); + typeComboBox.addItemListener(itemListener); + setTypeComboBoxPane(typeComboBox); + } + + protected void setTypeComboBoxPane (UIComboBox typeComboBox) { + this.add(typeComboBox, BorderLayout.NORTH); + } + + public void setComboBoxModel(boolean isDate) { + if (this.isDate != isDate) { + this.isDate = isDate; + this.typeComboBox.setSelectedIndex(0); + if (isDate) { + for (int i = 0; i < DATE_TYPES.length; i++) { + this.typeComboBox.addItem(DATE_TYPES[i]); + } + for (int i = 0; i < TYPES.length; i++) { + this.typeComboBox.removeItemAt(1); + } + } else { + for (int i = 0; i < TYPES.length; i++) { + this.typeComboBox.addItem(TYPES[i]); + } + for (int i = 0; i < DATE_TYPES.length; i++) { + this.typeComboBox.removeItemAt(1); + } + } + } + } + + @Override + public void registerNameListener(GlobalNameListener listener) { + globalNameListener = listener; + } + + public void registerChangeListener(UIObserverListener listener) { + typeComboBox.registerChangeListener(listener); + textField.registerChangeListener(listener); + } + + @Override + public boolean shouldResponseNameListener() { + return false; + } + + @Override + public void setGlobalName(String name) { + + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java b/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java index 237a5659a..bb3ccf38b 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java @@ -299,15 +299,16 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple Background borderImage = style.getBorderImage(); if (borderImage instanceof ImageBackground) { // 图片类型边框 - Image image = ((ImageBackground) borderImage).getImage(); - int[] ninePoint = ((ImageBackground) borderImage).getNinePoint(); + ImageBackground imageBackground = (ImageBackground) borderImage; + Image image = imageBackground.getImage(); if (image != null) { this.borderLineCombo.selectBorderImage(); this.imagePreviewPane.setImageWithSuffix(((ImageBackground) borderImage).getImageWithSuffix()); this.tweakNinePointButton.setEnabled(true); this.borderImageOpacityPane.populateBean(style.getBorderImageOpacity()); - if (ninePoint != null && ninePoint.length == 4 && ninePoint[0] > 0 && ninePoint[1] > 0 && ninePoint[2] > 0 && ninePoint[3] > 0) { + int[] ninePoint = ((ImageBackground) borderImage).getNinePoint(); + if (ninePoint != null && ninePoint.length == 4 && ninePoint[0] >= 0 && ninePoint[1] >= 0 && ninePoint[2] >= 0 && ninePoint[3] >= 0) { this.ninePoint = Arrays.copyOf(ninePoint, 4); } else { this.ninePoint = new int[4]; @@ -487,6 +488,7 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private int ninePointBottom = -1; private static final int MIN_NINE_POINT = 0; + private static final int MIN_GAP_PARALLEL_LINES = 1; private int imgWidth; private int imgHeight; @@ -757,8 +759,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private void onNinePointTopChanged(int value) { if (value < MIN_NINE_POINT) { value = MIN_NINE_POINT; - } else if (value >= imgHeight - ninePointBottom) { - value = imgHeight - ninePointBottom - MIN_NINE_POINT; + } else if (value >= imgHeight - ninePointBottom - MIN_GAP_PARALLEL_LINES) { + value = imgHeight - ninePointBottom - MIN_GAP_PARALLEL_LINES; } this.ninePointTop = value; repaint(); @@ -767,8 +769,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private void onNinePointBottomChanged(int value) { if (value < MIN_NINE_POINT) { value = MIN_NINE_POINT; - } else if (value >= imgHeight - ninePointTop) { - value = imgHeight - ninePointTop - MIN_NINE_POINT; + } else if (value >= imgHeight - ninePointTop - MIN_GAP_PARALLEL_LINES) { + value = imgHeight - ninePointTop - MIN_GAP_PARALLEL_LINES; } this.ninePointBottom = value; repaint(); @@ -777,8 +779,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private void onNinePointLeftChanged(int value) { if (value < MIN_NINE_POINT) { value = MIN_NINE_POINT; - } else if (value >= imgWidth - ninePointRight) { - value = imgWidth - ninePointRight - MIN_NINE_POINT; + } else if (value >= imgWidth - ninePointRight - MIN_GAP_PARALLEL_LINES) { + value = imgWidth - ninePointRight - MIN_GAP_PARALLEL_LINES; } this.ninePointLeft = value; repaint(); @@ -787,8 +789,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private void onNinePointRightChanged(int value) { if (value < MIN_NINE_POINT) { value = MIN_NINE_POINT; - } else if (value >= imgWidth - ninePointLeft) { - value = imgWidth - ninePointLeft - MIN_NINE_POINT; + } else if (value >= imgWidth - ninePointLeft - MIN_GAP_PARALLEL_LINES) { + value = imgWidth - ninePointLeft - MIN_GAP_PARALLEL_LINES; } this.ninePointRight = value; repaint(); diff --git a/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java b/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java index 460e838c5..a0a8e6b11 100644 --- a/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java +++ b/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java @@ -3,6 +3,7 @@ package com.fr.design.javascript; import com.fr.base.BaseFormula; import com.fr.base.Parameter; import com.fr.base.extension.FileExtension; +import com.fr.design.border.UITitledBorder; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.DialogActionAdapter; @@ -15,6 +16,10 @@ import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.icombobox.UIComboBoxRenderer; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itableeditorpane.ParameterTableModel; +import com.fr.design.gui.itableeditorpane.UITableEditAction; +import com.fr.design.gui.itableeditorpane.UITableEditorPane; +import com.fr.design.gui.itableeditorpane.UITableModelAdapter; import com.fr.design.gui.itextfield.UITextField; import com.fr.design.gui.itree.filetree.TemplateFileTree; import com.fr.design.hyperlink.AbstractHyperLinkPane; @@ -23,32 +28,40 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.DesignerContext; -import com.fr.design.scrollruler.ModLineBorder; import com.fr.file.filetree.IOFileNodeFilter; import com.fr.general.GeneralUtils; import com.fr.js.ExportJavaScript; +import com.fr.js.SingleJavaScript; import com.fr.stable.ParameterProvider; import com.fr.stable.StringUtils; import javax.swing.AbstractButton; +import javax.swing.AbstractCellEditor; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.DefaultComboBoxModel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.JTable; import javax.swing.SwingUtilities; +import javax.swing.event.CellEditorListener; +import javax.swing.event.ChangeEvent; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; +import javax.swing.table.TableCellEditor; import java.awt.BorderLayout; import java.awt.CardLayout; +import java.awt.Color; import java.awt.Component; -import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -59,21 +72,20 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane EXPORT_TYPES_MAP = new HashMap<>(); - private static final String CURRENT_TEMPLATE = "current"; - private static final String DEFAULT_FILENAME = "default"; - + private static final Map FILENAME_TYPE_MAP = new HashMap<>(); + private static final Map PARAMETER_TYPE_MAP = new HashMap<>(); + private static final String DEFAULT = "default"; + private static final String CUSTOM = "custom"; + private static final String CURRENT_TEMPLATE = "cur"; + private static final String OTHER_TEMPLATE = "other"; static { EXPORT_TYPES_MAP.put(ExportJavaScript.EXPORT_PDF, Toolkit.i18nText("Fine-Design_Basic_Export_JS_PDF")); @@ -82,134 +94,601 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane list = parameterViewPane.update(); - HashSet tempSet = new HashSet<>(); - for (int i = 0; i < list.size(); i++) { - if (StringUtils.isEmpty(list.get(i).getName())) { - continue; + private JPanel initFileNamePane() { + UILabel nameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename") + ":"); + fileNameRadioGroup = new ExportRadioGroup(); + defaultNameRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Default")); + defaultNameRadio.setSelected(true); + customNameRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Custom")); + addRadioToGroup(fileNameRadioGroup, defaultNameRadio, customNameRadio); + fileNameFormulaEditor = new FormulaEditor(Toolkit.i18nText("Fine-Design_Report_Parameter_Formula")); + fileNameFormulaEditor.setVisible(false); + fileNameFormulaEditor.setEnabled(false); + UILabel fileNameTipLabel = new UILabel("" + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Title_Tip_Front") + "\\/:*?\"<>|" + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Title_Tip_Back") + ""); + fileNameTipLabel.setVisible(false); + fileNameRadioGroup.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (defaultNameRadio.isSelected()) { + fileNameFormulaEditor.setVisible(false); + fileNameFormulaEditor.setEnabled(false); + fileNameTipLabel.setVisible(false); + } else { + fileNameFormulaEditor.setVisible(true); + fileNameFormulaEditor.setEnabled(true); + fileNameTipLabel.setVisible(true); } - if (tempSet.contains(list.get(i).toString())) { - list.remove(i); - FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Parameter_Duplicate_Name") + "!"); - return; - } - tempSet.add(list.get(i).toString()); } + }); + Component[][] components = new Component[][]{{nameLabel, defaultNameRadio, customNameRadio, fileNameFormulaEditor}}; + JPanel fileNameRadioPane = TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{p, p, p, p}); + + JPanel fileNameTipPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + fileNameTipPane.add(fileNameTipLabel); + + JPanel fileNamePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + fileNamePane.add(fileNameRadioPane, BorderLayout.NORTH); + fileNamePane.add(fileNameTipPane, BorderLayout.CENTER); + fileNameTipPane.setBorder(BorderFactory.createEmptyBorder(5, 2, 5, 2)); + fileNamePane.setBorder(BorderFactory.createEmptyBorder(5, 2, 5, 2)); + return fileNamePane; + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Export_JS_Setting"); + } + + } + + // 其他模板 + class OtherTemplatePane extends BasicPane { + + private UITableEditorPane editorPane; + + public OtherTemplatePane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Template_Other"))); + + editorPane = new UITableEditorPane<>(new ExportJSTableModel()); + + this.add(editorPane, BorderLayout.CENTER); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Export_JS_Setting"); + } + + } + + class ExportJSTableModel extends UITableModelAdapter { + + private static final long serialVersionUID = -3697206557955735642L; + + public ExportJSTableModel() { + super(new String[]{ + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Template_File"), + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Type"), + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename"), + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Custom"), + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Parameters_Setting"), + StringUtils.EMPTY}); + this.setColumnClass(new Class[]{ + ExportTemplateChooser.class, + ExportTypeCombobox.class, + FileNameCombobox.class, + FileNameFormulaEditor.class, + ParameterCombobox.class, + ParameterSettingButton.class + }); + this.setDefaultEditor(ExportTemplateChooser.class, new ExportTemplateChooser()); + this.setDefaultEditor(ExportTypeCombobox.class, new ExportTypeCombobox()); + this.setDefaultEditor(FileNameCombobox.class, new FileNameCombobox()); + this.setDefaultEditor(FileNameFormulaEditor.class, new FileNameFormulaEditor()); + this.setDefaultEditor(ParameterCombobox.class, new ParameterCombobox()); + this.setDefaultEditor(ParameterSettingButton.class, new ParameterSettingButton()); + this.createTable().getColumnModel().getColumn(2).setMaxWidth(60); + this.createTable().getColumnModel().getColumn(4).setMaxWidth(60); + this.createTable().getColumnModel().getColumn(5).setMaxWidth(40); + } + + @Override + public UITableEditAction[] createAction() { + return new UITableEditAction[] {new AddJSAction(), new DeleteAction()}; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + SingleJavaScript js = this.getList().get(rowIndex); + switch (columnIndex) { + case 0: + return js.getTemplatePath(); + case 1: + return EXPORT_TYPES_MAP.get(js.getExportType()); + case 2: + return js.isDefaultFileName() ? Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Default") : Toolkit.i18nText("Fine-Design_Basic_Export_JS_Custom"); + case 3: + return js.getFileName(); + case 4: + return js.isExtendParameters() ? Toolkit.i18nText("Fine-Design_Basic_Export_JS_Extend_Parameters") : Toolkit.i18nText("Fine-Design_Basic_Export_JS_Custom"); + case 5: + return js.getParameters(); } - }); - extendParametersCheckBox.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - parameterViewPane.setVisible(e.getStateChange() == ItemEvent.DESELECTED); + return null; + } + + @Override + public boolean isCellEditable(int row, int col) { + if(col == 3) { + // 命名详情 + return this.getList().get(row) != null && !this.getList().get(row).isDefaultFileName(); + } + if (col == 5) { + // 参数设置按钮 + return this.getList().get(row) != null && !this.getList().get(row).isExtendParameters(); + } + return true; + } + + private class AddJSAction extends AddTableRowAction { + + public AddJSAction() { + } - }); - JPanel paramsPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - paramsPane.setBorder(BorderFactory.createTitledBorder(new ModLineBorder(ModLineBorder.TOP), Toolkit.i18nText("Fine-Design_Basic_Parameters"))); - paramsPane.add(extendParametersCheckBox, BorderLayout.NORTH); - JPanel dynamicPaneWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); - dynamicPaneWrapper.add(parameterViewPane); - paramsPane.add(dynamicPaneWrapper, BorderLayout.CENTER); - return paramsPane; - } - private JPanel initFileNamePane() { - UILabel nameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename") + ":"); - fileNameRadioGroup = new ExportRadioGroup(); - defaultNameRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Default")); - defaultNameRadio.setSelected(true); - customNameRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Custom")); - addRadioToGroup(fileNameRadioGroup, defaultNameRadio, customNameRadio); - fileNameFormulaEditor = new FormulaEditor(Toolkit.i18nText("Fine-Design_Report_Parameter_Formula")); - fileNameFormulaEditor.setEnabled(false); - fileNameRadioGroup.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - if (defaultNameRadio.isSelected()) { - fileNameFormulaEditor.setEnabled(false); + super.actionPerformed(e); + if (otherTemplatePane.editorPane.getTableModel().getList().size() <= 50) { + addJS(); } else { - fileNameFormulaEditor.setEnabled(true); + FineJOptionPane.showMessageDialog(otherTemplatePane, Toolkit.i18nText("Fine-Design_Basic_Export_JS_Batch_Export_Limit")); } } - }); - Component[][] components = new Component[][]{{nameLabel, defaultNameRadio, customNameRadio, fileNameFormulaEditor}}; - JPanel fileNameRadioPane = TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{p, p, p, p}); - - JPanel fileNameTipPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - UILabel fileNameTipLabel = new UILabel("" + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Title_Tip_Front") + "\\/:*?\"<>|" + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Title_Tip_Back") + ""); - fileNameTipPane.add(fileNameTipLabel); - - JPanel fileNamePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - fileNamePane.add(fileNameRadioPane, BorderLayout.NORTH); - fileNamePane.add(fileNameTipPane, BorderLayout.CENTER); - fileNameTipPane.setBorder(BorderFactory.createEmptyBorder(5,2,5,2)); - fileNamePane.setBorder(BorderFactory.createEmptyBorder(5,2,5,2)); - return fileNamePane; - } + } - private JPanel initExportTypePane() { - UILabel typeLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Type") + ":"); - exportTypeComboBox = new UIComboBox(new DefaultComboBoxModel()); - DefaultComboBoxModel comboBoxModel = (DefaultComboBoxModel) exportTypeComboBox.getModel(); - String[] allExportTypes = new String[]{ExportJavaScript.EXPORT_PDF, ExportJavaScript.EXPORT_EXCEL_PAGE, ExportJavaScript.EXPORT_EXCEL_SIMPLE, ExportJavaScript.EXPORT_EXCEL_SHEET, ExportJavaScript.EXPORT_WORD, ExportJavaScript.EXPORT_IMAGE}; - for (int i = 0; i < allExportTypes.length; i++) { - comboBoxModel.addElement(allExportTypes[i]); + private void addJS() { + SingleJavaScript js = new SingleJavaScript(); + addRow(js); + fireTableDataChanged(); + table.getSelectionModel().setSelectionInterval(table.getRowCount() - 1, table.getRowCount() - 1); } - this.exportTypeComboBox.setRenderer(new UIComboBoxRenderer() { + + // 导出文件选择 + class ExportTemplateChooser extends AbstractCellEditor implements TableCellEditor { + + private static final long serialVersionUID = -9112506131272704717L; + private JPanel reportletNamePane; + private UITextField reportPathTextField; + private UIButton browserButton; + + public ExportTemplateChooser() { + reportletNamePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + // 路径输入框 + reportPathTextField = new UITextField(7); + reportPathTextField.setEnabled(false); + reportletNamePane.add(reportPathTextField, BorderLayout.WEST); + + // 选择路径按钮 + browserButton = new UIButton("..."); + browserButton.setVisible(true); + reportletNamePane.add(browserButton, BorderLayout.EAST); + browserButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent evt) { + final ReportletPane reportletPane = new ReportletPane(); + reportletPane.setSelectedReportletPath(reportPathTextField.getText()); + BasicDialog reportletDialog = reportletPane.showWindow(SwingUtilities.getWindowAncestor(ExportJavaScriptPane.this)); + + reportletDialog.addDialogActionListener(new DialogActionAdapter() { + @Override + public void doOk() { + reportPathTextField.setText(reportletPane.getSelectedReportletPath()); + } + }); + reportletDialog.setVisible(true); + } + }); + this.addCellEditorListener(new CellEditorListener() { + + @Override + public void editingCanceled(ChangeEvent e) { + + } + + @Override + public void editingStopped(ChangeEvent e) { + if (table.getSelectedRow() == -1){ + return; + } + SingleJavaScript js = getList().get(table.getSelectedRow()); + String value = StringUtils.trimToNull(reportPathTextField.getText()); + js.setTemplatePath(value); + js.setCurrentTemplate(false); + fireTableDataChanged(); + } + }); + + } @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - if (value instanceof String) { - this.setText(EXPORT_TYPES_MAP.get(value)); + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + reportPathTextField.setText((String) value); + return reportletNamePane; + } + + @Override + public Object getCellEditorValue() { + return reportPathTextField.getText(); + } + } + + // 导出方式下拉框 + class ExportTypeCombobox extends AbstractCellEditor implements TableCellEditor { + + private static final long serialVersionUID = -6564079764032351372L; + + public ExportTypeCombobox() { + exportTypeComboBox = getComboBoxWithModel(new String[]{ExportJavaScript.EXPORT_PDF, ExportJavaScript.EXPORT_EXCEL_PAGE, ExportJavaScript.EXPORT_EXCEL_SIMPLE, ExportJavaScript.EXPORT_EXCEL_SHEET, ExportJavaScript.EXPORT_WORD, ExportJavaScript.EXPORT_IMAGE} + , EXPORT_TYPES_MAP); + this.addCellEditorListener(new CellEditorListener() { + + @Override + public void editingCanceled(ChangeEvent e) { + + } + + @Override + public void editingStopped(ChangeEvent e) { + if (table.getSelectedRow() == -1){ + return; + } + SingleJavaScript js = getList().get(table.getSelectedRow()); + Object ob = exportTypeComboBox.getSelectedItem(); + if (ob != null) { + String value = ob.toString(); + js.setExportType(value); + } + fireTableDataChanged(); + } + }); + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + exportTypeComboBox.setSelectedItem(value); + return exportTypeComboBox; + } + + @Override + public Object getCellEditorValue() { + Object ob = exportTypeComboBox.getSelectedItem(); + if (ob != null) { + return ob.toString(); } - return this; + return ExportJavaScript.EXPORT_PDF; } - }); + } + + // 命名方式下拉框 + class FileNameCombobox extends AbstractCellEditor implements TableCellEditor { + + private static final long serialVersionUID = 1829005772744444269L; + private UIComboBox fileNameComboBox; + + public FileNameCombobox() { + fileNameComboBox = getComboBoxWithModel(new String[]{DEFAULT, CUSTOM}, FILENAME_TYPE_MAP); + this.addCellEditorListener(new CellEditorListener() { + + @Override + public void editingCanceled(ChangeEvent e) { + + } + + @Override + public void editingStopped(ChangeEvent e) { + if (table.getSelectedRow() == -1){ + return; + } + SingleJavaScript js = getList().get(table.getSelectedRow()); + Object ob = fileNameComboBox.getSelectedItem(); + if (ob != null) { + String value = ob.toString(); + js.setDefaultFileName(StringUtils.equals(value, DEFAULT)); + } + fireTableDataChanged(); + } + }); + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + fileNameComboBox.setSelectedItem(value); + return fileNameComboBox; + } + + @Override + public Object getCellEditorValue() { + return fileNameComboBox.getSelectedItem().toString(); + } + } + + // 命名方式公式框 + class FileNameFormulaEditor extends AbstractCellEditor implements TableCellEditor { + + private static final long serialVersionUID = 7120075192535645493L; + private FormulaEditor fileNameFormulaEditor; + + public FileNameFormulaEditor() { + fileNameFormulaEditor = new FormulaEditor(Toolkit.i18nText("Fine-Design_Report_Parameter_Formula")); + this.addCellEditorListener(new CellEditorListener() { + + @Override + public void editingCanceled(ChangeEvent e) { + + } + + @Override + public void editingStopped(ChangeEvent e) { + if (table.getSelectedRow() == -1){ + return; + } + SingleJavaScript js = getList().get(table.getSelectedRow()); + String value = fileNameFormulaEditor.getUITextField().getText(); + js.setFileName(value); + fireTableDataChanged(); + } + }); + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + fileNameFormulaEditor.setValue(BaseFormula.createFormulaBuilder().build()); + return fileNameFormulaEditor; + } + + @Override + public Object getCellEditorValue() { + return fileNameFormulaEditor.getUITextField().getText(); + } + + public FormulaEditor getFileNameEditor() { + return fileNameFormulaEditor; + } + } + + //参数设置下拉框 + class ParameterCombobox extends AbstractCellEditor implements TableCellEditor { + + private static final long serialVersionUID = 2630964402770993584L; + private UIComboBox parameterSetting; + + public ParameterCombobox() { + parameterSetting = getComboBoxWithModel(new String[]{DEFAULT, CUSTOM}, PARAMETER_TYPE_MAP); + this.addCellEditorListener(new CellEditorListener() { + + @Override + public void editingCanceled(ChangeEvent e) { + + } + + @Override + public void editingStopped(ChangeEvent e) { + if (table.getSelectedRow() == -1){ + return; + } + SingleJavaScript js = getList().get(table.getSelectedRow()); + Object ob = parameterSetting.getSelectedItem(); + if (ob != null) { + String value = ob.toString(); + js.setExtendParameters(StringUtils.equals(value, DEFAULT)); + } + fireTableDataChanged(); + } + }); + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + parameterSetting.setSelectedItem(value); + return parameterSetting; + } + + @Override + public Object getCellEditorValue() { + return parameterSetting.getSelectedItem().toString(); + } + } + + // 参数设置按钮 + class ParameterSettingButton extends AbstractCellEditor implements TableCellEditor { + + private static final long serialVersionUID = 4021592871993049137L; + private UIButton paraButton; + private ParameterSettingPane paraSettingPane; + ParameterProvider[] parameterArr; + + public ParameterSettingButton() { + paraSettingPane = new ParameterSettingPane(); + paraButton = new UIButton(); + paraButton.setBackground(Color.GRAY); + paraButton.addMouseListener(new MouseAdapter() { + + @Override + public void mousePressed(MouseEvent e) { + BasicDialog dialog = paraSettingPane.showWindow(SwingUtilities.getWindowAncestor(ExportJavaScriptPane.this)); + dialog.addDialogActionListener(new DialogActionAdapter() { + @Override + public void doOk() { + List parameterList = paraSettingPane.getParameterList(); + parameterArr = parameterList.toArray(new Parameter[parameterList.size()]); + } + }); + dialog.setVisible(true); + } + + }); + this.addCellEditorListener(new CellEditorListener() { + + @Override + public void editingCanceled(ChangeEvent e) { + + } + + @Override + public void editingStopped(ChangeEvent e) { + if (table.getSelectedRow() == -1){ + return; + } + SingleJavaScript js = getList().get(table.getSelectedRow()); + js.setParameters(parameterArr); + fireTableDataChanged(); + } + }); + + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + paraSettingPane.refresh(new ArrayList<>(Arrays.asList((ParameterProvider[]) value))); + return paraButton; + } + + @Override + public Object getCellEditorValue() { + return paraSettingPane.getParameterList(); + } + } + + // 参数设置弹出框 + class ParameterSettingPane extends BasicPane { + + private ReportletParameterViewPane parameterViewPane; + + public ParameterSettingPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + parameterViewPane = new ReportletParameterViewPane(ParameterTableModel.NO_CHART_USE, getValueEditorPane(), getValueEditorPane()); + addListener(parameterViewPane); + this.add(parameterViewPane); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Export_JS_Parameters_Setting"); + } + + public List getParameterList() { + return parameterViewPane.update(); + } + + public void refresh(List list) { + parameterViewPane.update(list); + } + + } + + } + + public ExportJavaScriptPane() { + initComponents(); + } + + private void initComponents() { + JPanel totalPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + totalPanel.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Setting"))); + + // 导出模板 + JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + JPanel chooseTemplatePane = initChooseTemplatePane(); + northPane.add(chooseTemplatePane, BorderLayout.NORTH); + + // 默认当前模板 + currentTemplatePane = new CurrentTemplatePane(); + otherTemplatePane = new OtherTemplatePane(); + templatePanel = FRGUIPaneFactory.createCardLayout_S_Pane(); + card = new CardLayout(); + templatePanel.setLayout(card); + templatePanel.add(CURRENT_TEMPLATE, currentTemplatePane); + templatePanel.add(OTHER_TEMPLATE, otherTemplatePane); + + totalPanel.add(northPane, BorderLayout.NORTH); + totalPanel.add(templatePanel, BorderLayout.CENTER); + + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.add(totalPanel); + } + + private JPanel initExportTypePane() { + UILabel typeLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Type") + ":"); + exportTypeComboBox = getComboBoxWithModel(new String[]{ExportJavaScript.EXPORT_PDF, ExportJavaScript.EXPORT_EXCEL_PAGE, ExportJavaScript.EXPORT_EXCEL_SIMPLE, ExportJavaScript.EXPORT_EXCEL_SHEET, ExportJavaScript.EXPORT_WORD, ExportJavaScript.EXPORT_IMAGE} + , EXPORT_TYPES_MAP); Component[][] components = new Component[][]{{typeLabel, exportTypeComboBox}}; JPanel exportTypePane = TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{p, p}); - exportTypePane.setBorder(BorderFactory.createEmptyBorder(5,2,5,2)); + exportTypePane.setBorder(BorderFactory.createEmptyBorder(5, 2, 5, 2)); return exportTypePane; } @@ -220,51 +699,28 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane parameterList = this.parameterViewPane.update(); + parameterList.clear(); + ParameterProvider[] parameters = js.getParameters(); + this.parameterViewPane.populate(parameters); + } } else { - this.extendParametersCheckBox.setSelected(false); - List parameterList = this.parameterViewPane.update(); - parameterList.clear(); - ParameterProvider[] parameters = ob.getParameters(); - this.parameterViewPane.populate(parameters); + OtherTemplatePane pane = (OtherTemplatePane) this.templatePanel.getComponent(1); + pane.editorPane.populate(ob.getJsList().toArray(new SingleJavaScript[ob.getJsList().size()])); } } @@ -309,32 +764,78 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane parameterList = parameterViewPane.update(); + if (!parameterList.isEmpty()) { + Parameter[] parameters = new Parameter[parameterList.size()]; + parameterList.toArray(parameters); + js.setParameters(parameters); + } + } + exportJavaScript.addJS(js); } else { - List parameterList = this.parameterViewPane.update(); - if (!parameterList.isEmpty()) { - Parameter[] parameters = new Parameter[parameterList.size()]; - parameterList.toArray(parameters); - exportJavaScript.setParameters(parameters); + List javaScripts = otherTemplatePane.editorPane.update(); + for (SingleJavaScript js : javaScripts) { + exportJavaScript.addJS(js); } } } - private String getTemplatePath() { - return currentTemplateRadio.isSelected() ? CURRENT_TEMPLATE : reportPathTextField.getText(); + private String getFileName() { + return currentTemplatePane.defaultNameRadio.isSelected() ? DEFAULT : currentTemplatePane.fileNameFormulaEditor.getUITextField().getText(); } - private String getFileName() { - return defaultNameRadio.isSelected() ? DEFAULT_FILENAME : fileNameFormulaEditor.getUITextField().getText(); + private UIComboBox getComboBoxWithModel(String[] itemTextArr, Map itemTextDic) { + UIComboBox comboBox = new UIComboBox(new DefaultComboBoxModel()); + DefaultComboBoxModel comboBoxModel = (DefaultComboBoxModel) comboBox.getModel(); + for (int i = 0; i < itemTextArr.length; i++) { + comboBoxModel.addElement(itemTextArr[i]); + } + comboBox.setRenderer(new UIComboBoxRenderer() { + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value instanceof String) { + this.setText(itemTextDic.get(value)); + } + return this; + } + }); + return comboBox; } + private void addListener(ReportletParameterViewPane paraPane) { + paraPane.addTableEditorListener(new TableModelListener() { + public void tableChanged(TableModelEvent e) { + List list = paraPane.update(); + HashSet tempSet = new HashSet<>(); + for (int i = 0; i < list.size(); i++) { + if (StringUtils.isEmpty(list.get(i).getName())) { + continue; + } + if (tempSet.contains(list.get(i).toString())) { + list.remove(i); + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Parameter_Duplicate_Name") + "!"); + return; + } + tempSet.add(list.get(i).toString()); + } + } + }); + } @Override public boolean accept(Object ob) { diff --git a/designer-base/src/main/java/com/fr/design/login/service/DesignerPassportManager.java b/designer-base/src/main/java/com/fr/design/login/service/DesignerPassportManager.java index 446a30f8b..19eefa85d 100644 --- a/designer-base/src/main/java/com/fr/design/login/service/DesignerPassportManager.java +++ b/designer-base/src/main/java/com/fr/design/login/service/DesignerPassportManager.java @@ -5,6 +5,7 @@ import com.fr.design.login.DesignerLoginType; import com.fr.design.upm.event.CertificateEvent; import com.fr.event.EventDispatcher; import com.fr.json.JSONObject; +import com.fr.stable.StringUtils; /** * @author Lanlan @@ -96,6 +97,14 @@ public class DesignerPassportManager { return uid; } + /** + * 登出帆软通行证 + */ + public void logout() { + saveUserInfo(-1, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, DesignerLoginType.UNKNOWN, StringUtils.EMPTY); + EventDispatcher.fire(CertificateEvent.LOGOUT, StringUtils.EMPTY); + } + /** * 保存登录信息 */ diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java b/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java index 0c10ac2e1..65a9a47d6 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java @@ -92,7 +92,7 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener } else if (jt.isOpening()) { showOpenStatus(); } else if (jt.isOpenFailed()) { - showOpenFailedCover(); + showOpenFailedCover(jt.getTemplateOpenFailedTip()); } else { hideCover(); } @@ -121,7 +121,8 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener layeredPane.moveToFront(loadingPane); } - public void showOpenFailedCover() { + public void showOpenFailedCover(String text) { + failedPane.setFailedTip(text); layeredPane.moveToFront(failedPane); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java index 588b4e256..a6734da91 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java @@ -1005,6 +1005,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer { button.addActionListener(actionListener); } button.setToolTipText(title); + button.setName(name); } public void processSnapChat() { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java index 89bb1b798..c342cc391 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java @@ -19,7 +19,6 @@ import com.fr.design.ExtraDesignClassManager; import com.fr.design.actions.TableDataSourceAction; import com.fr.design.actions.edit.RedoAction; import com.fr.design.actions.edit.UndoAction; -import com.fr.design.actions.file.BatchCompileAction; import com.fr.design.actions.file.SaveAsTemplateAction; import com.fr.design.actions.file.SaveTemplateAction; import com.fr.design.actions.file.WebPreviewUtils; @@ -68,7 +67,12 @@ import com.fr.form.ui.NoneWidget; import com.fr.form.ui.Widget; import com.fr.general.ComparatorUtils; import com.fr.general.IOUtils; +import com.fr.locale.InterProviderFactory; import com.fr.log.FineLoggerFactory; +import com.fr.nx.app.designer.utils.CptAndCptxCompatibilityUtil; +import com.fr.nx.app.designer.utils.CptCompileUtil; +import com.fr.nx.cptx.entry.metadata.CptxMetadata; +import com.fr.nx.cptx.utils.CptxFileUtils; import com.fr.plugin.context.PluginContext; import com.fr.plugin.context.PluginRuntime; import com.fr.nx.app.designer.toolbar.CompileAction; @@ -130,6 +134,8 @@ public abstract class JTemplate> private JComponent centerPane; private DesignModelAdapter designModel; private PreviewProvider previewType; + private String templateOpenFailedTip; + /** * 统计模板制作耗时 * @@ -951,7 +957,7 @@ public abstract class JTemplate> } protected boolean export() throws Exception { - return this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(editingFILE)); + return this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(getEditingFILE())); } @@ -969,7 +975,7 @@ public abstract class JTemplate> } else if (DesignerMode.isAuthorityEditing()) { return new ShortCut[]{new SaveTemplateAction(this), new UndoAction(this), new RedoAction(this)}; } else { - return new ShortCut[]{new SaveTemplateAction(this), new SaveAsTemplateAction(this), new BatchCompileAction(), new UndoAction(this), new RedoAction(this)}; + return new ShortCut[]{new SaveTemplateAction(this), new SaveAsTemplateAction(this), new UndoAction(this), new RedoAction(this)}; } } @@ -1125,35 +1131,49 @@ public abstract class JTemplate> /** * 判断是否是新版设计器 * + * @param showTipPane 是否需要展示弹窗 * @return 是返回true */ - public boolean isNewDesigner() { + public boolean isNewDesigner(boolean showTipPane) { String xmlDesignerVersion = getTarget().getXMLDesignerVersion(); if (isLowerThanHBB(xmlDesignerVersion)) { String info = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Open-New_Form_Tip"); String moreInfo = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Server_Version_Tip_More_Info"); - new InformationWarnPane(info, moreInfo, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")).show(); + if (showTipPane) { + new InformationWarnPane(info, moreInfo, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")).show(); + } return true; } return false; } + public boolean isNewDesigner() { + return isNewDesigner(true); + } + /** * 是否是就版本设计器 * + * @param showTipPane 是否需要展示弹窗 * @return 是就返回true */ - public boolean isOldDesigner() { + public boolean isOldDesigner(boolean showTipPane) { String xmlDesignerVersion = getTarget().getXMLDesignerVersion(); if (isHigherThanCurrent(xmlDesignerVersion)) { String infor = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Template_Version_Not_Match", DesignUtils.parseVersion(xmlDesignerVersion)); String moreInfo = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Server_Version_Tip_More_Info"); - new InformationWarnPane(infor, moreInfo, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")).show(); + if (showTipPane) { + new InformationWarnPane(infor, moreInfo, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")).show(); + } return true; } return false; } + public boolean isOldDesigner() { + return isOldDesigner(true); + } + /** * */ @@ -1406,9 +1426,7 @@ public abstract class JTemplate> * @return 按钮组 */ public UIButton[] createExtraButtons() { - UIButton[] uiButtons = new UIButton[]{ - (UIButton) new CompileAction().createToolBarComponent() - }; + UIButton[] uiButtons = new UIButton[0]; Set providers = ExtraDesignClassManager.getInstance().getArray(DesignerFrameUpButtonProvider.XML_TAG); for (DesignerFrameUpButtonProvider provider : providers) { uiButtons = ArrayUtils.addAll(uiButtons, provider.getUpButtons(getMenuState())); @@ -1434,6 +1452,7 @@ public abstract class JTemplate> }; button.setToolTipText(getTemplateTheme().getName()); button.setText(getTemplateTheme().getName()); + button.setName(getTemplateTheme().getName()); button.setAlignmentX(SwingConstants.LEFT); button.set4ToolbarButton(); button.setEnabled(true); @@ -1460,7 +1479,27 @@ public abstract class JTemplate> public abstract String route(); public String getTemplateName() { - return getEditingFILE().getName(); + return getEditingFILE().getName() + compatibilityTip(); + } + + /** + * 设置新引擎后,有不支持的功能时,设计器中模板的标题需要加上“兼容模式”或者“不支持分页引擎”来提示用户 + * */ + private String compatibilityTip() { + if (!CptAndCptxCompatibilityUtil.isEngineXEnable(this.getTarget(), getEditingFILE().getPath())){ + return StringUtils.EMPTY; + } + String path = this.getEditingFILE().getPath(); + CptxMetadata metadata = CptxFileUtils.getMetadata(path); + //是否是兼容模式,兼容模式下,设置了新引擎的cpt和cptx的后缀不同 + if (metadata != null && metadata.isForceCpt()) { + if (path.endsWith(".cptx")){ + return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Compatibility_Mode"); + } else if (path.endsWith(".cpt")){ + return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Paging_Engine_Not_Work"); + } + } + return StringUtils.EMPTY; } public String getTemplatePredefinedStyle() { @@ -1529,6 +1568,8 @@ public abstract class JTemplate> @Override public void run() { callBackForSave(); + //在保存后的回调中执行预编译流程 + CptCompileUtil.compile(JTemplate.this); } }); @@ -1557,7 +1598,7 @@ public abstract class JTemplate> if (editingFILE == null || editingFILE instanceof MemFILE) { return false; } - this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(editingFILE)); + export(); this.editingFILE = editingFILE; return true; } else { @@ -1599,6 +1640,10 @@ public abstract class JTemplate> worker.addSuccessCallback(new Runnable() { @Override public void run() { + boolean isChangedFile = !JTemplate.this.saved; + if (isChangedFile){ + CptCompileUtil.compile(JTemplate.this); + } callBackForSave(); // 当前打开的是正在保存的模板才刷新 if (ComparatorUtils.equals(JTemplate.this.template.getTemplateID(), @@ -1608,7 +1653,6 @@ public abstract class JTemplate> DesignerFrameFileDealerPane.getInstance().refresh(); } }); - return worker; } @@ -1659,6 +1703,14 @@ public abstract class JTemplate> result = result || provider.saveToNewFile(this.editingFILE.getPath(), this); } if (!result) { + /* + * 1.在CptCompileUtil::haveChanged改变报表引擎属性 + * 2.在这三种情况下:1.cptx文件另存为cpt文件 2.cptx另存为cptx文件 3.设置了新引擎的cpt文件另存为cpt文件, + * 因为文件的编译目录改变了,需要重新预编译,因此设置jTemplate的保存状态为false + * */ + if (CptAndCptxCompatibilityUtil.needRecompile(oldName, this)){ + this.saved = false; + } result = this.saveRealFile(); // 更换最近打开 DesignerEnvManager.getEnvManager().replaceRecentOpenedFilePath(oldName, this.getPath()); @@ -1741,6 +1793,14 @@ public abstract class JTemplate> themeAttrMark.setDark(theme.isDark()); } + public String getTemplateOpenFailedTip() { + return templateOpenFailedTip; + } + + public void setTemplateOpenFailedTip(String templateOpenFailedTip) { + this.templateOpenFailedTip = templateOpenFailedTip; + } + @Override public void setTemplateTheme(TemplateTheme newTheme, TemplateThemeCompatible compatible) { ThemedTemplate.super.setTemplateTheme(newTheme, compatible); @@ -1748,4 +1808,4 @@ public abstract class JTemplate> templateThemeButton.setText(name); templateThemeButton.setToolTipText(name); } -} +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java index b07071057..f15b3517f 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java @@ -116,6 +116,7 @@ public class NorthRegionContainerPane extends JPanel { if (!DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isEnabled()) { ad.createAlphaFinePane().setVisible(false); } + northEastPane.add(ad.createGuideEntryPane()); northEastPane.add(ad.createNotificationCenterPane()); OSSupportCenter.buildAction(new OSBasedAction() { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java b/designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java index 132569c23..63ab984da 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java @@ -24,6 +24,7 @@ public class OpenFailedPane extends JPanel { private UILabel label; private MessageWithLink link; + private String defaultFailedText; public OpenFailedPane() { this.setLayout(new LayoutManager() { @@ -83,11 +84,18 @@ public class OpenFailedPane extends JPanel { }); } }; + this.defaultFailedText = link.getText(); link.setBackground(Color.WHITE); this.add(label); this.add(link); } - + public void setFailedTip(String text) { + if (StringUtils.isEmpty(text)) { + this.link.setText(defaultFailedText); + } else { + this.link.setText(text); + } + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/Guide.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/Guide.java new file mode 100644 index 000000000..9469f931a --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/Guide.java @@ -0,0 +1,189 @@ +package com.fr.design.mainframe.guide.base; + +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.guide.collect.GuideCollector; +import com.fr.design.mainframe.guide.scene.GuideScene; +import com.fr.design.mainframe.guide.ui.GuideCompleteDialog; +import com.fr.design.mainframe.guide.ui.GuideManageDialog; +import com.fr.stable.StringUtils; + +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; + +public class Guide { + private String id; + private String name; + private String description; + private String completeMessage; + private GuideView guideView; + private GuideLifecycle lifecycle; + private boolean isComplete; + private GuideScene scene; + + public Guide() { + this(null, null, null); + } + + public Guide(String id, String name, String description) { + this.id = id; + this.name = name; + this.description = description; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDescription() { + if (StringUtils.isNotEmpty(description)) { + return description; + } + return name; + } + + public String getCompleteMessage() { + return completeMessage; + } + + public void setCompleteMessage(String completeMessage) { + this.completeMessage = completeMessage; + } + + public void setGuideView(GuideView guideView) { + this.guideView = guideView; + } + + public GuideView getGuideView() { + return guideView; + } + + public void setComplete(boolean complete) { + isComplete = complete; + } + + public boolean isComplete() { + return isComplete; + } + + public void setScene(GuideScene scene) { + this.scene = scene; + } + + public GuideScene getScene() { + return scene; + } + + /** + * 开启引导流程 + */ + public void go() { + DesignerContext.getDesignerFrame().setExtendedState(JFrame.MAXIMIZED_BOTH); + // 同时只能启动一个引导 + if (GuideManager.getInstance().getCurrentGuide() != null) { + return; + } + GuideManager.getInstance().setCurrentGuide(this); + guideView.showLoading(); + + new SwingWorker() { + @Override + protected Boolean doInBackground() { + try { + if (lifecycle != null && !lifecycle.prepared()) { + return false; + } + return true; + } catch (Exception e) { + e.printStackTrace(); + guideView.hideLoading(); + terminate(); + return false; + } + } + + @Override + protected void done() { + try { + if (get()) { + start(); + } + } catch (Exception e) { + e.printStackTrace(); + guideView.hideLoading(); + terminate(); + } + } + }.execute(); + } + + public void start() { + guideView.hideLoading(); + if (scene != null) { + guideView.setScene(scene); + guideView.showGuide(); + if (lifecycle != null) { + lifecycle.onStart(); + } + } else { + complete(); + } + } + + public void complete() { + if (lifecycle != null) { + lifecycle.onComplete(); + } + setComplete(true); + GuideCollector.getInstance().saveInfo(); + guideView.dismissGuide(); + GuideCompleteDialog.getInstance().showDialog(getCompleteMessage()); + end(); + } + + public void terminate() { + if (lifecycle != null) { + lifecycle.onTerminate(); + } + end(); + } + + public void end() { + guideView.dismissGuide(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (lifecycle != null) { + lifecycle.onEnd(); + } + GuideManager.getInstance().setCurrentGuide(null); + GuideManageDialog.getInstance().showDialog(); + } + }); + + } + + public void registerLifecycle(GuideLifecycle lifecycle) { + this.lifecycle = lifecycle; + } + + public void removeGuideLifecycle() { + this.lifecycle = null; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideBuilder.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideBuilder.java new file mode 100644 index 000000000..a1974bf92 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideBuilder.java @@ -0,0 +1,51 @@ +package com.fr.design.mainframe.guide.base; + +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.guide.scene.GuideScene; + +public class GuideBuilder { + private Guide guide; + + public static GuideBuilder newInstance() { + return new GuideBuilder(); + } + + public GuideBuilder() { + guide = new Guide(); + guide.setGuideView(new GuideView(DesignerContext.getDesignerFrame(), guide)); + } + + public GuideBuilder setID(String id) { + guide.setId(id); + return this; + } + + public GuideBuilder setName(String name) { + guide.setName(name); + return this; + } + + public GuideBuilder setDescription(String description) { + guide.setDescription(description); + return this; + } + + public GuideBuilder setCompleteMessage(String message) { + guide.setCompleteMessage(message); + return this; + } + + public GuideBuilder addScene(GuideScene scene) { + guide.setScene(scene); + return this; + } + + public GuideBuilder registerLifecycle(GuideLifecycle lifecycle) { + guide.registerLifecycle(lifecycle); + return this; + } + + public Guide getGuide() { + return guide; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideGroup.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideGroup.java new file mode 100644 index 000000000..cd5e0b579 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideGroup.java @@ -0,0 +1,55 @@ +package com.fr.design.mainframe.guide.base; + +import java.util.ArrayList; +import java.util.List; + +public class GuideGroup { + private List guideList; + private String id; + private String name; + + public GuideGroup(String id, String name) { + this.id = id; + this.name = name; + guideList = new ArrayList<>(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void addGuide(Guide guide) { + guideList.add(guide); + } + + public List getGuideList() { + return guideList; + } + + public List getCompleteGuideList() { + List complete = new ArrayList<>(); + for (Guide guide : getGuideList()) { + if (guide.isComplete()) { + complete.add(guide); + } + } + return complete; + } + + public boolean isCompleteAll() { + return getCompleteGuideList().size() == getGuideList().size(); + } + + public boolean isCompleteSome() { + List completeGuides = getCompleteGuideList(); + return completeGuides.size() > 0 && completeGuides.size() < getGuideList().size(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycle.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycle.java new file mode 100644 index 000000000..2ddfd975f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycle.java @@ -0,0 +1,32 @@ +package com.fr.design.mainframe.guide.base; + +public interface GuideLifecycle{ + /** + * 准备环境 + * @return 返回true引导可继续执行 + */ + boolean prepared(); + + /** + * 开始引导教程 + */ + void onStart(); + + /** + * 完成引导教程 + */ + + void onComplete(); + + /** + * 终止引导教程 + */ + + void onTerminate(); + + /** + * 结束引导教程 + */ + void onEnd(); + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycleAdaptor.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycleAdaptor.java new file mode 100644 index 000000000..c67f47e35 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycleAdaptor.java @@ -0,0 +1,28 @@ +package com.fr.design.mainframe.guide.base; + +public abstract class GuideLifecycleAdaptor implements GuideLifecycle{ + @Override + public boolean prepared() { + return true; + } + + @Override + public void onStart() { + + } + + @Override + public void onComplete() { + + } + + @Override + public void onTerminate() { + + } + + @Override + public void onEnd() { + + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideManager.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideManager.java new file mode 100644 index 000000000..08c46688d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideManager.java @@ -0,0 +1,113 @@ +package com.fr.design.mainframe.guide.base; + +import com.fr.design.mainframe.guide.collect.GuideCollector; +import com.fr.stable.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +public class GuideManager { + private static GuideManager guideManager; + + private Guide currentGuide; + private List guideVersionList; + + public static GuideManager getInstance() { + if (guideManager == null) { + guideManager = new GuideManager(); + } + return guideManager; + } + + public GuideManager() { + guideVersionList = new ArrayList<>(); + } + + public Guide getCurrentGuide() { + return currentGuide; + } + + public void setCurrentGuide(Guide currentGuide) { + this.currentGuide = currentGuide; + } + + public void addGuideGroup(String version, GuideGroup guideGroup) { + GuideVersion guideVersion = getGuideVersion(version); + if (guideVersion == null) { + guideVersion = new GuideVersion(version); + guideVersionList.add(guideVersion); + } + guideVersion.addGuideGroup(guideGroup); + } + + public void addGuide(String groupId, Guide guide) { + GuideGroup guideGroup = getGuideGroup(groupId); + if (guideGroup != null) { + guideGroup.addGuide(guide); + } + } + + public List getGuideVersionList() { + return guideVersionList; + } + + public List getAllGuide() { + List guideList = new ArrayList<>(); + for (GuideVersion version : guideVersionList) { + for (GuideGroup group : version.getGuideGroupList()) { + for (Guide guide : group.getGuideList()) { + guideList.add(guide); + } + } + } + return guideList; + } + + public GuideVersion getGuideVersion(String version) { + for (GuideVersion guideVersion : guideVersionList) { + if (StringUtils.equals(version, guideVersion.getVersion())) { + return guideVersion; + } + } + return null; + } + + public GuideGroup getGuideGroup(String groupId) { + for (GuideVersion version : guideVersionList) { + for (GuideGroup group : version.getGuideGroupList()) { + if (StringUtils.equals(groupId, group.getId())) { + return group; + } + } + } + return null; + } + + public Guide getGuide(String guideId) { + for (GuideVersion version : guideVersionList) { + for (GuideGroup group : version.getGuideGroupList()) { + for (Guide guide : group.getGuideList()) { + if (StringUtils.equals(guideId, guide.getId())) { + return guide; + } + } + } + } + return null; + } + + public void completeAll() { + for (GuideVersion version : guideVersionList) { + for (GuideGroup group : version.getGuideGroupList()) { + for (Guide guide : group.getGuideList()) { + guide.setComplete(true); + } + } + } + GuideCollector.getInstance().saveInfo(); + } + + public void clearAll() { + guideVersionList.clear(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideVersion.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideVersion.java new file mode 100644 index 000000000..3c365aa94 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideVersion.java @@ -0,0 +1,29 @@ +package com.fr.design.mainframe.guide.base; + +import java.util.ArrayList; +import java.util.List; + +public class GuideVersion { + private String version; + private List guideGroupList; + public GuideVersion(String version) { + guideGroupList = new ArrayList<>(); + this.version = version; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public List getGuideGroupList() { + return guideGroupList; + } + + public void addGuideGroup(GuideGroup guideGroup) { + guideGroupList.add(guideGroup); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideView.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideView.java new file mode 100644 index 000000000..aa277adbb --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideView.java @@ -0,0 +1,129 @@ +package com.fr.design.mainframe.guide.base; + +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.guide.scene.AbstractGuideScene; +import com.fr.design.mainframe.guide.scene.GuideScene; +import com.fr.design.mainframe.guide.ui.GuideLoadingGlassPane; +import com.fr.design.utils.gui.GUICoreUtils; + +import javax.swing.JDialog; +import javax.swing.SwingUtilities; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Window; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class GuideView extends JDialog { + private static GuideView guideView; + private Guide invoker; + private GuideScene scene; + private Color modalColor; + private float modalOpacity; + private Window window; + + public static GuideView getInstance(Guide guide) { + if (guideView == null) { + guideView = new GuideView(DesignerContext.getDesignerFrame(), guide); + } + return guideView; + } + + public GuideView(Window window) { + super(window); + this.setUndecorated(true); + this.window = window; + this.modalColor = Color.BLACK; + this.modalOpacity = 0.6f; + this.setPreferredSize(window.getSize()); + this.setSize(window.getSize()); + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + setBg(); + this.setGlassPane(new GuideLoadingGlassPane()); + DesignerContext.getDesignerFrame().addWindowListener(new WindowAdapter() { + + @Override + public void windowDeiconified(WindowEvent e) { + if (isVisible()) { + updateGuideViewLocation(); + // window 带透明的dialog在窗口最小化后再打开会不渲染,这边试了下重新设置visible可行 + setVisible(false); + setVisible(true); + } + } + }); + } + + public GuideView(Window window, Guide guide) { + this(window); + this.invoker = guide; + } + + public void setModalColor(Color color) { + modalColor = color; + setBg(); + } + + public void setModalOpacity(float opacity){ + modalOpacity = opacity; + setBg(); + } + + private void setBg() { + Color newColor = new Color(modalColor.getRed(), modalColor.getGreen(), modalColor.getBlue(), (int) (255 * modalOpacity)); + this.setBackground(newColor); + } + + public void setScene(GuideScene scene) { + if (scene instanceof AbstractGuideScene) { + ((AbstractGuideScene) scene).setContainer(this); + } + this.scene = scene; + } + + public void showGuide() { + updateGuideViewLocation(); + this.setVisible(true); + if (scene != null) { + scene.start(); + } else { + GuideManager.getInstance().getCurrentGuide().complete(); + } + } + + public void dismissGuide() { + this.getLayeredPane().removeAll(); + revalidate(); + repaint(); + setVisible(false); + dispose(); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + } + + public void showLoading() { + updateGuideViewLocation(); + this.setVisible(true); + this.getGlassPane().setVisible(true); + } + + public void hideLoading() { + this.getGlassPane().setVisible(false); + repaint(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + setVisible(false); + } + }); + } + + private void updateGuideViewLocation() { + GUICoreUtils.centerWindow(window, this); + this.setSize(getSize()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/collect/GuideCollector.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/collect/GuideCollector.java new file mode 100644 index 000000000..4c4c40f76 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/collect/GuideCollector.java @@ -0,0 +1,155 @@ +package com.fr.design.mainframe.guide.collect; + +import com.fr.base.io.XMLReadHelper; +import com.fr.design.mainframe.guide.base.Guide; +import com.fr.design.mainframe.guide.base.GuideManager; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLReadable; +import com.fr.stable.xml.XMLTools; +import com.fr.stable.xml.XMLable; +import com.fr.stable.xml.XMLableReader; +import com.fr.third.javax.xml.stream.XMLStreamException; +import com.fr.third.org.apache.commons.io.FileUtils; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +public class GuideCollector implements XMLable { + private static final String ROOT_XML = "GuideCollector"; + private static final String GUIDE_XML = "Guide"; + private static final String FILE_NAME = "guide.info"; + private static GuideCollector collector; + + private boolean showHint; + private List cacheGuides; + + public static GuideCollector getInstance() { + if (collector == null) { + collector = new GuideCollector(); + } + return collector; + } + + public GuideCollector() { + cacheGuides = new ArrayList<>(); + } + + public boolean isShowHint() { + return showHint; + } + + public void setShowHint(boolean showHint) { + this.showHint = showHint; + saveInfo(); + } + + public void load() { + for(Guide cacheGuide : cacheGuides) { + Guide guide = GuideManager.getInstance().getGuide(cacheGuide.getId()); + if (guide != null) { + guide.setComplete(cacheGuide.isComplete()); + } + } + } + + public void saveInfo() { + cacheGuides = GuideManager.getInstance().getAllGuide(); + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + XMLTools.writeOutputStreamXML(this, out); + out.flush(); + out.close(); + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + FileUtils.writeStringToFile(getInfoFile(), fileContent, StandardCharsets.UTF_8); + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage()); + } + } + + private File getInfoFile() { + File file = new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), FILE_NAME)); + try { + if (!file.exists()) { + file.createNewFile(); + } + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } + return file; + } + + public void loadFromFile() { + if (!getInfoFile().exists()) { + return; + } + XMLableReader reader = null; + try (InputStream in = new FileInputStream(getInfoFile())) { + reader = XMLReadHelper.createXMLableReader(in, XMLPrintWriter.XML_ENCODER); + if (reader == null) { + return; + } + reader.readXMLObject(this); + } catch (FileNotFoundException e) { + } catch (XMLStreamException | IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (XMLStreamException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } + + @Override + public void readXML(XMLableReader xmLableReader) { + String tagName = xmLableReader.getTagName(); + if (tagName.equals(ROOT_XML)) { + showHint = xmLableReader.getAttrAsBoolean("showHint", false); + xmLableReader.readXMLObject(new XMLReadable() { + public void readXML(XMLableReader reader) { + String tagName = reader.getTagName(); + if (tagName.equals(GUIDE_XML)) { + Guide guide = new Guide(); + guide.setId(reader.getAttrAsString("id", null)); + guide.setComplete(reader.getAttrAsBoolean("isComplete", false)); + cacheGuides.add(guide); + } + + } + }); + } + } + + @Override + public void writeXML(XMLPrintWriter writer) { + writer.startTAG(ROOT_XML); + writer.attr("showHint", showHint); + for(Guide guide : GuideManager.getInstance().getAllGuide()) { + writer.startTAG(GUIDE_XML); + writer.attr("id", guide.getId()); + writer.attr("isComplete", guide.isComplete()); + writer.end(); + } + writer.end(); + + + } + + @Override + public Object clone() throws CloneNotSupportedException { + return null; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/AbstractGuideScene.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/AbstractGuideScene.java new file mode 100644 index 000000000..f0d74789d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/AbstractGuideScene.java @@ -0,0 +1,480 @@ +package com.fr.design.mainframe.guide.scene; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.guide.base.GuideManager; +import com.fr.design.mainframe.guide.base.GuideView; +import com.fr.design.mainframe.guide.utils.ScreenImage; +import com.fr.design.mainframe.guide.tip.BubbleTip; +import com.fr.design.mainframe.guide.tip.GuideTip; +import com.fr.stable.StringUtils; + +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import java.awt.AWTException; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Component; +import java.awt.Composite; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; + +public abstract class AbstractGuideScene extends JPanel implements GuideScene { + private static final int DEFAULT_ARROW_HEIGHT = 12; + private static final int DEFAULT_ARROW_WIDTH = 18; + + private GuideScene nextScene; + private SceneFilter sceneFilter; + private GuideSceneLifecycle lifecycle; + private GuideView container; + private List targetList; + private List highlightList; + private Component nextButton; + private List pointsList; + + + public AbstractGuideScene() { + this.setLayout(null); + this.setOpaque(false); + targetList = new ArrayList<>(); + highlightList = new ArrayList<>(); + pointsList = new ArrayList<>(); + } + + /** + * 根据设计器上组件添加高亮区域视图, + * JComponent 采用组件绘制方式 + * Component 采用屏幕截图方式 + * @param component 设计器组件对象 + * @return + */ + public boolean addTarget(Component component) { + try { + if (component == null || container == null) { + return false; + } + + Point point = SwingUtilities.convertPoint(component,0,0, container.getRootPane()); + Rectangle rectangle = new Rectangle(point, component.getSize()); + BufferedImage image; + + if (component instanceof JComponent) { + JComponent jComponent = (JComponent) component; + image = ScreenImage.createImage(jComponent); + } else if (component instanceof Window) { + image = ScreenImage.createImage(component); + } else { + image = captureImage(component); + } + targetList.add(component); + highlightList.add(getTargetComponentWithImage(image, rectangle)); + return true; + } catch (AWTException e) { + e.printStackTrace(); + GuideManager.getInstance().getCurrentGuide().terminate(); + return false; + } + } + + /** + * 根据设计器上选定区域获取高亮视图,采用截屏的方式 + * @param rectangle 选定区域,相对屏幕 + * @return + */ + public boolean addTarget(Rectangle rectangle) { + try { + targetList.add(null); + BufferedImage image = captureImage(rectangle); + highlightList.add(getTargetComponentWithImage(image, rectangle)); + return true; + } catch (AWTException e) { + e.printStackTrace(); + GuideManager.getInstance().getCurrentGuide().terminate(); + return false; + } + } + + /** + * 根据设计器组件,选定其中某个区域,添加高亮视图 + * @param component 设计器组件 + * @param origin 相对组件的区域 + * @return + */ + public boolean addTarget(Component component, Rectangle origin) { + try { + if (component == null) { + return false; + } + Point point = SwingUtilities.convertPoint(component,0,0, container.getRootPane()); + + origin = origin.intersection(new Rectangle(0,0,component.getWidth(), component.getHeight())); + Rectangle rectangle = new Rectangle(point.x + origin.x, point.y + origin.y, origin.width, origin.height); + + BufferedImage image; + + if (component instanceof JComponent) { + JComponent jComponent = (JComponent) component; + image = ScreenImage.createImage(jComponent, origin); + } else { + image = ScreenImage.createImage(component).getSubimage(origin.x, origin.y, origin.width, origin.height); + } + targetList.add(component); + highlightList.add(getTargetComponentWithImage(image, rectangle)); + return true; + } catch (AWTException e) { + e.printStackTrace(); + GuideManager.getInstance().getCurrentGuide().terminate(); + return false; + } + } + + /** + * 添加自定义组件 + * @param component 自定义组件 + * @param rectangle 相对引导页的区域 + * @return + */ + public boolean addCustomTarget(Component component, Rectangle rectangle) { + if (component == null) { + return false; + } + component.setBounds(rectangle); + targetList.add(component); + highlightList.add(component); + return true; + } + + public boolean addCustomTarget(Component component, Point location) { + return addCustomTarget(component, new Rectangle(location, component.getPreferredSize())); + } + + protected List getTargetList() { + return targetList; + } + + public List getHighlightList() { + return highlightList; + } + + private UILabel getTargetComponentWithImage(BufferedImage image, Rectangle rectangle) { + ImageIcon ic = new ImageIcon(image); + UILabel label = new UILabel(ic); + label.setOpaque(true); + label.setBounds(rectangle); + return label; + } + + private BufferedImage captureImage(Rectangle rectangle) throws AWTException { + container.setVisible(false); + BufferedImage image = ScreenImage.createImage(rectangle); + showContainer(); + return image; + } + + private BufferedImage captureImage(Component component) throws AWTException { + container.setVisible(false); + BufferedImage image = ScreenImage.createImage(component); + showContainer(); + return image; + } + + private void showContainer() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + container.setVisible(true); + container.toFront(); + container.requestFocus(); + } + }); + } + + + /** + * 自定义位置添加气泡提示组件 + * @param title 提示标题 + * @param content 提示内容 + * @param direction 气泡窗口位置方向 + * @param anchor 气泡窗口箭头坐标 + * @param bubbleTailStart 气泡窗口箭头坐标相对于位置方向交叉轴的比例(从左到右,从上到下) + */ + public void addBubbleTip(String title, String content, GuideTip.Direction direction, Point anchor, float bubbleTailStart) { + BubbleTip bt = new BubbleTip(title, content, direction, bubbleTailStart); + bt.setAnchor(anchor); + this.add(bt.getTip()); + } + + /** + * 以上一个添加的引导目标窗口为基础,添加对应的气泡窗 + * @param title 提示标题 + * @param content 提示内容 + * @param direction + * @param anchorStart + * @param bubbleTailStart + */ + public void addBubbleTip(String title, String content, GuideTip.Direction direction, float anchorStart, float bubbleTailStart) { + if (highlightList.size() == 0) { + return; + } + Component lastTarget = highlightList.get(highlightList.size() - 1); + Rectangle bounds = lastTarget.getBounds(); + Point anchor = new Point(0,0); + if (direction == GuideTip.Direction.TOP) { + anchor = new Point(bounds.x + (int)(bounds.width * anchorStart), bounds.y); + } else if (direction == GuideTip.Direction.BOTTOM) { + anchor = new Point(bounds.x + (int)(bounds.width * anchorStart), bounds.y + bounds.height); + } else if (direction == GuideTip.Direction.LEFT) { + anchor = new Point(bounds.x, bounds.y + (int)(bounds.height * anchorStart)); + } else if (direction == GuideTip.Direction.RIGHT) { + anchor = new Point(bounds.x + bounds.width, bounds.y + (int) (bounds.height * anchorStart)); + } + addBubbleTip(title, content, direction, anchor, bubbleTailStart); + } + + public void addBubbleTip(String title, String content, GuideTip.Direction direction) { + addBubbleTip(title, content, direction, 0.5f, 0.5f); + } + + public void addBubbleTip(String title, GuideTip.Direction direction) { + addBubbleTip(title, StringUtils.EMPTY, direction); + } + + public void addTip(GuideTip tip) { + this.add(tip.getTip()); + } + + public void addLineArrow(Point... points) { + pointsList.add(points); + } + + public void setContainer(GuideView container) { + this.container = container; + } + + public GuideView getContainer() { + return container; + } + + @Override + public GuideScene nextScene(GuideScene scene) { + nextScene = scene; + return nextScene; + } + + @Override + public void addSceneFilter(SceneFilter filter) { + sceneFilter = filter; + } + + @Override + public void start() { + clear(); + if (lifecycle != null && !lifecycle.prepared()) { + return; + } + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + showScene(); + } + }); + } + + @Override + public void showScene() { + if (container != null) { + container.setContentPane(AbstractGuideScene.this); + setBounds(0, 0 , getSceneWidth(), getSceneWidth()); + + // show target + for (int index = highlightList.size() - 1; index >= 0; index--) { + add(highlightList.get(index)); + } + // show next button + if (nextButton != null) { + nextButton.setBounds((getSceneWidth() - 60) / 2, getSceneHeight() - 100, 60, 30); + add(nextButton); + } + + container.revalidate(); + container.repaint(); + } + showContainer(); + if (lifecycle != null) { + lifecycle.onShow(); + } + } + + @Override + public void complete() { + container.getLayeredPane().remove(this); + container.repaint(); + + if (lifecycle != null && !lifecycle.onComplete()) { + return; + } + if (sceneFilter != null) { + nextScene = sceneFilter.getFilterScene(); + } + if (nextScene != null) { + if (nextScene instanceof AbstractGuideScene) { + ((AbstractGuideScene) nextScene).setContainer(container); + } + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + nextScene.start(); + } + }); + } else { + GuideManager.getInstance().getCurrentGuide().complete(); + } + } + + @Override + public void registerLifecycle(GuideSceneLifecycle lifecycle) { + this.lifecycle = lifecycle; + } + + @Override + public void removeLifecycle() { + this.lifecycle = null; + } + + public void showNextButton() { + UIButton nextButton = new UIButton("Next"); + nextButton.setPreferredSize(new Dimension(60, 30)); + nextButton.setOpaque(false); + nextButton.setFont(nextButton.getFont().deriveFont(20)); + nextButton.setRoundBorder(true, 8); + nextButton.setForeground(Color.WHITE); + nextButton.setNormalPainted(false); + nextButton.setPressedPainted(false); + nextButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + complete(); + } + }); + this.nextButton = nextButton; + } + + private int getSceneWidth() { + if (container == null) { + return 0; + } + return container.getLayeredPane().getWidth(); + + } + + private int getSceneHeight() { + if (container == null) { + return 0; + } + return container.getLayeredPane().getHeight(); + } + + private void clear() { + targetList = new ArrayList<>(); + highlightList = new ArrayList<>(); + this.nextButton = null; + this.removeAll(); + invalidate(); + repaint(); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + if (pointsList.isEmpty()) { + return; + } + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); + g2d.setColor(Color.WHITE); + for (Point[] points : pointsList) { + if (points.length <= 1) { + continue; + } + Point startPoint = points[0]; + Point endPoint = startPoint; + for (int index = 1; index < points.length; index++) { + startPoint = endPoint; + endPoint = points[index]; + g2d.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y); + } + + drawArrow(g2d, startPoint, endPoint); + } + g2d.setComposite(oldComposite); + } + + /** + * 根据最后两点坐标计算出三角箭头的三个点坐标,绘制箭头 + * 这里实现以终点坐标为坐标轴圆点计算 + * @param start 起始点坐标 + * @param end 重点坐标 + */ + private void drawArrow(Graphics2D g2d, Point start, Point end) { + try{ + double dealtPointX = start.x - end.x; + double dealtPointY = -(start.y - end.y); + + double pointDistance = calDistance(dealtPointX, dealtPointY); + double triangleHeight = Math.min(DEFAULT_ARROW_HEIGHT, pointDistance); + double triangleWidth = triangleHeight * (DEFAULT_ARROW_WIDTH / 2) / DEFAULT_ARROW_WIDTH; + if (triangleHeight < 1 || triangleWidth < 1 || pointDistance < 1) { + return; + } + + double pointAngle; + double abs = 1; + if (dealtPointX == 0) { + pointAngle = Math.PI / 2; + } else { + pointAngle = Math.atan(dealtPointY / dealtPointX); + } + if (dealtPointY < 0) { + pointAngle += Math.PI; + abs = -1; + } + + double deltaAngle = Math.atan(triangleWidth / triangleHeight); + double triangleDistance = calDistance(triangleWidth, triangleHeight); + + Point p1 =calPoint(end, triangleDistance, pointAngle - deltaAngle, abs); + Point p2 = calPoint(end, triangleDistance, pointAngle + deltaAngle, abs); + + int xPoints[] = {end.x, p1.x, p2.x}; + int yPoints[] = {end.y, p1.y, p2.y}; + + g2d.fillPolygon(xPoints, yPoints, 3); + } catch (Exception e) { + e.printStackTrace(); + GuideManager.getInstance().getCurrentGuide().terminate(); + } + } + + private double calDistance(double x, double y) { + return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + } + + private Point calPoint(Point relativePoint, double distance, double angle, double abs) { + int x = (int)(relativePoint.x + abs * distance * Math.cos(angle)); + int y = (int)(relativePoint.y - abs * distance * Math.sin(angle)); + return new Point(x, y); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/ClickScene.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/ClickScene.java new file mode 100644 index 000000000..6217f41e7 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/ClickScene.java @@ -0,0 +1,123 @@ +package com.fr.design.mainframe.guide.scene; + +import com.fr.design.mainframe.guide.base.GuideManager; + +import javax.swing.AbstractButton; +import javax.swing.ButtonModel; +import javax.swing.SwingUtilities; +import java.awt.Component; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ClickScene extends AbstractGuideScene{ + public enum ClickType { + LEFT, LEFT_DOUBLE, RIGHT + } + + public void addClickTarget(Component component, ClickType clickType) { + addClickTarget(component, clickType, false); + } + + public void addClickTarget(Component component, ClickType clickType, boolean isDispatch) { + if (super.addTarget(component)) { + addTargetClickListener(clickType, isDispatch); + } + } + + public void addClickTarget(Rectangle rectangle, ClickType clickType) { + if (super.addTarget(rectangle)) { + addTargetClickListener(clickType,false); + } + } + + public void addClickTarget(Component component, Rectangle rectangle, ClickType clickType) { + if (super.addTarget(component, rectangle)) { + addTargetClickListener(clickType, false); + } + } + + public void addCustomClickTarget(Component component, Rectangle rectangle, ClickType clickType) { + if (super.addCustomTarget(component, rectangle)) { + addTargetClickListener(clickType, false); + } + } + + public void addCustomClickTarget(Component component, Point location, ClickType clickType) { + if (super.addCustomTarget(component, location)) { + addTargetClickListener(clickType, false); + } + } + + private void addTargetClickListener(ClickType clickType, boolean isDispatch) { + Component highlight = getHighlightList().get(getHighlightList().size() - 1); + Component target = getTargetList().get(getTargetList().size() - 1); + highlight.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON1) { + if ((e.getClickCount() == 1 && clickType == ClickType.LEFT) || (e.getClickCount() == 2 && clickType == ClickType.LEFT_DOUBLE)) { + if (isDispatch) { + redispatchMouseEvent(e, target); + } + complete(); + } + } else if (e.getButton() == MouseEvent.BUTTON3 && clickType == ClickType.RIGHT) { + if (isDispatch) { + redispatchMouseEvent(e, target); + } + complete(); + } + } + + @Override + public void mousePressed(MouseEvent e) { + if (isDispatch) { + if (target instanceof AbstractButton) { + AbstractButton b = (AbstractButton) target; + b.setFocusable(false); + } + redispatchMouseEvent(e, target); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + if (isDispatch) { + redispatchMouseEvent(e, target); + } + } + + @Override + public void mouseEntered(MouseEvent e) { + if (isDispatch) { + redispatchMouseEvent(e, target); + } + } + + @Override + public void mouseExited(MouseEvent e) { + if (isDispatch) { + redispatchMouseEvent(e, target); + } + } + }); + } + + private void redispatchMouseEvent(MouseEvent e, Component component) { + component.dispatchEvent(new MouseEvent(component, e.getID(), e + .getWhen(), e.getModifiers(), e.getX(), + e.getY(), e.getClickCount(), e.isPopupTrigger())); + } + + @Override + public void showScene() { + // 交互类的 scene 如果没有高亮内容块载,需要及时终止Guide,否则就没法去掉模态框影响到设计器主功能的使用了 + if (this.getComponentCount() == 0) { + GuideManager.getInstance().getCurrentGuide().terminate(); + } else { + super.showScene(); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DisplayScene.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DisplayScene.java new file mode 100644 index 000000000..21ebe972d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DisplayScene.java @@ -0,0 +1,37 @@ +package com.fr.design.mainframe.guide.scene; + +import java.util.Timer; +import java.util.TimerTask; + +public class DisplayScene extends AbstractGuideScene { + private long delay; + private static final long DEFAULT_DELAY = 1000; + private static Timer displayTimer = new Timer(); + + public DisplayScene() { + this(DEFAULT_DELAY); + } + + public DisplayScene(long delay) { + super(); + this.delay = delay; + } + + public void setDelay(long delay) { + this.delay = delay; + } + + @Override + public void showScene() { + super.showScene(); + // 实例化Timer类 + displayTimer.schedule(new TimerTask() { + @Override + public void run() { + complete(); + displayTimer.purge(); + } + }, delay); + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DragScene.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DragScene.java new file mode 100644 index 000000000..fdf8b2d4d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DragScene.java @@ -0,0 +1,64 @@ +package com.fr.design.mainframe.guide.scene; + +import com.fr.design.mainframe.guide.scene.drag.DragAndDropDragGestureListener; + +import java.awt.Component; +import java.awt.Rectangle; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetDropEvent; + +public class DragScene extends AbstractGuideScene{ + public enum DragType{ + NONE, FROM, TO + } + + public void addDragTarget(Component component, DragType type) { + if (super.addTarget(component)) { + addDragTargetListener(type); + } + } + + public void addDragTarget(Rectangle rectangle, DragType type) { + if (super.addTarget(rectangle)) { + addDragTargetListener(type); + } + } + + public void addDragTarget(Component component, Rectangle rectangle, DragType type) { + if (super.addTarget(component, rectangle)) { + addDragTargetListener(type); + } + } + + public void addCustomDragTarget(Component component, Rectangle rectangle, DragType type) { + if (super.addCustomTarget(component, rectangle)) { + addDragTargetListener(type); + } + } + + private void addDragTargetListener(DragType dragType) { + Component target = getHighlightList().get(getHighlightList().size() - 1); + + if (dragType == DragType.FROM) { + new DragAndDropDragGestureListener(target, DnDConstants.ACTION_COPY_OR_MOVE){ + @Override + public void dragDropEnd(DragSourceDropEvent dsde) { + if (dsde.getDropSuccess()) { + complete(); + } + } + }; + } else if (dragType == DragType.TO) { + target.setDropTarget(new DropSceneTarget()); + } + } + + private class DropSceneTarget extends DropTarget { + @Override + public synchronized void drop(DropTargetDropEvent dtde) { + dtde.dropComplete(true); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideScene.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideScene.java new file mode 100644 index 000000000..e62ca4d9a --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideScene.java @@ -0,0 +1,18 @@ +package com.fr.design.mainframe.guide.scene; + + +public interface GuideScene { + GuideScene nextScene(GuideScene scene); + + void addSceneFilter(SceneFilter filter); + + void start(); + + void showScene(); + + void complete(); + + void registerLifecycle(GuideSceneLifecycle lifecycle); + + void removeLifecycle(); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycle.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycle.java new file mode 100644 index 000000000..36734a619 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycle.java @@ -0,0 +1,21 @@ +package com.fr.design.mainframe.guide.scene; + +public interface GuideSceneLifecycle { + /** + * 引导场景准备工作 + * 给 scene 添加 target 应该在这个阶段处理 + * @return 返回true自动执行scene, 返回false需要手动触发 + */ + boolean prepared(); + + /** + * scene 显示后 + */ + void onShow(); + + /** + * scene 交互完成后处理 + * @return 返回true自动进入下一个scene,返回false需要手动触发 + */ + boolean onComplete(); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycleAdaptor.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycleAdaptor.java new file mode 100644 index 000000000..1ed99dca6 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycleAdaptor.java @@ -0,0 +1,18 @@ +package com.fr.design.mainframe.guide.scene; + +public abstract class GuideSceneLifecycleAdaptor implements GuideSceneLifecycle { + @Override + public boolean prepared() { + return true; + } + + @Override + public void onShow() { + + } + + @Override + public boolean onComplete() { + return true; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/SceneFilter.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/SceneFilter.java new file mode 100644 index 000000000..ea4ccf28f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/SceneFilter.java @@ -0,0 +1,5 @@ +package com.fr.design.mainframe.guide.scene; + +public interface SceneFilter { + GuideScene getFilterScene(); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/drag/DragAndDropDragGestureListener.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/drag/DragAndDropDragGestureListener.java new file mode 100644 index 000000000..25979925d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/drag/DragAndDropDragGestureListener.java @@ -0,0 +1,60 @@ +package com.fr.design.mainframe.guide.scene.drag; + +import com.fr.general.ComparatorUtils; +import org.jetbrains.annotations.NotNull; + +import java.awt.Component; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; + +public class DragAndDropDragGestureListener extends DragSourceAdapter implements DragGestureListener { + private Component component; + + public DragAndDropDragGestureListener(Component component, int actions) { + this.component = component; + DragSource source = new DragSource(); + source.createDefaultDragGestureRecognizer(component, actions, this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + if (component != null) { + try { + DragAndDropTransferable dragAndDropTransferable = new DragAndDropTransferable(component); + dge.startDrag(DragSource.DefaultCopyDrop, dragAndDropTransferable, this); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + private static class DragAndDropTransferable implements Transferable { + private Component component; + + public DragAndDropTransferable(Component component) { + this.component = component; + } + + DataFlavor[] flavors = {new DataFlavor(Component.class, "Component")}; + + public DataFlavor[] getTransferDataFlavors() { + return flavors; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + for (DataFlavor df : flavors) { + if (ComparatorUtils.equals(df, flavor)) { + return true; + } + } + return false; + } + @NotNull + public Object getTransferData(DataFlavor df) { + return component; + } + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/tip/BubbleTip.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/tip/BubbleTip.java new file mode 100644 index 000000000..d3d1c040d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/tip/BubbleTip.java @@ -0,0 +1,97 @@ +package com.fr.design.mainframe.guide.tip; + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerFrame; +import com.fr.design.mainframe.guide.base.Guide; +import com.fr.design.mainframe.guide.base.GuideManager; +import com.fr.design.mainframe.guide.ui.bubble.Bubble; +import com.fr.design.mainframe.guide.ui.bubble.BubbleWithClose; + +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class BubbleTip implements GuideTip { + private BubbleWithClose bubbleBox; + private Point anchor; + + /** + * + * @param title 标题 + * @param content 内容 + * @param direction 气泡提示相对anchor的方向,这里方向会和气泡组件箭头方向相反 + * @param tailStart 气泡尾巴相对当前边垂直方向偏移位置比例,值在0-1范围 + */ + public BubbleTip(String title, String content, Direction direction, float tailStart) { + bubbleBox = new BubbleWithClose(title, content, getBubbleBoxTailDirection(direction), tailStart); + bubbleBox.addCloseActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Guide currentGuide = GuideManager.getInstance().getCurrentGuide(); + if (currentGuide != null) { + + int returnVal = FineJOptionPane.showConfirmDialog( + currentGuide.getGuideView(), + Toolkit.i18nText("Fine-Design_Guide_Option_Warning_Terminal"), + Toolkit.i18nText("Fine-Design_Basic_Confirm"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + if (returnVal == JOptionPane.YES_OPTION) { + currentGuide.terminate(); + } + } + } + }); + } + @Override + public JComponent getTip() { + if(anchor == null) { + return new BubbleWithClose(bubbleBox.getTitle(), bubbleBox.getContent(), Bubble.TailDirection.TOP, 0); + } else { + setBubbleBoxBound(); + return bubbleBox; + } + } + + /** + * 设置锚点坐标 + * 这里可以指定气泡组件箭头坐标的箭头坐标 + * @param anchor + */ + public void setAnchor(Point anchor) { + this.anchor = anchor; + } + + private void setBubbleBoxBound() { + int bubbleW = bubbleBox.getPreferredSize().width; + int bubbleH = bubbleBox.getPreferredSize().height; + if (bubbleBox.isTailHorizontal()) { + int x = bubbleBox.isTailLeft() ? anchor.x : anchor.x - bubbleW; + int y = anchor.y - (int) (bubbleH * bubbleBox.getTailStart()); + bubbleBox.setBounds(x, y, bubbleW, bubbleH); + } else if (bubbleBox.isTailVertical()) { + int x = anchor.x - (int) (bubbleW * bubbleBox.getTailStart()); + int y = bubbleBox.isTailTop() ? anchor.y : anchor.y - bubbleH; + bubbleBox.setBounds(x, y, bubbleW, bubbleH); + } + } + + private Bubble.TailDirection getBubbleBoxTailDirection(Direction direction) { + switch (direction) { + case TOP: + return Bubble.TailDirection.BOTTOM; + case BOTTOM: + return Bubble.TailDirection.TOP; + case LEFT: + return Bubble.TailDirection.RIGHT; + case RIGHT: + default: + return Bubble.TailDirection.LEFT; + } + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/tip/GuideTip.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/tip/GuideTip.java new file mode 100644 index 000000000..e1573601f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/tip/GuideTip.java @@ -0,0 +1,14 @@ +package com.fr.design.mainframe.guide.tip; + +import javax.swing.JComponent; +import java.awt.Point; + +public interface GuideTip { + enum Direction { + TOP, BOTTOM, LEFT, RIGHT + } + + JComponent getTip(); + + void setAnchor(Point anchor); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/BubbleHint.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/BubbleHint.java new file mode 100644 index 000000000..56f978731 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/BubbleHint.java @@ -0,0 +1,74 @@ +package com.fr.design.mainframe.guide.ui; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.mainframe.guide.ui.bubble.Bubble; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.ActionListener; + +public class BubbleHint extends Bubble { + private UIButton confirmButton; + + public BubbleHint() { + super(TailDirection.TOP, 0.9f); + initComponent(); + } + + private void initComponent() { + this.setLayout(new BorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder(10 + Bubble.TAIL_HEIGHT, 15, 10, 15)); + this.setPreferredSize(new Dimension(220, 140)); + + JPanel contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(false, VerticalFlowLayout.CENTER, 0, 0); + contentPane.setOpaque(false); + + UILabel title = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Tips_Title")); + title.setFont(title.getFont().deriveFont(16.0f)); + title.setForeground(new Color(62, 155, 249)); + title.setPreferredSize(new Dimension(190, 30)); + title.setHorizontalAlignment(SwingConstants.CENTER); + title.setBorder(BorderFactory.createEmptyBorder(0,0,5,0)); + + UILabel content1 = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Tips_Content1")); + content1.setPreferredSize(new Dimension(190,20)); + content1.setHorizontalAlignment(SwingConstants.CENTER); + + UILabel content2 = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Tips_Content2")); + content2.setPreferredSize(new Dimension(190,20)); + content2.setHorizontalAlignment(SwingConstants.CENTER); + + JPanel buttonContainer= FRGUIPaneFactory.createCenterFlowZeroGapBorderPane(); + buttonContainer.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0)); + buttonContainer.setPreferredSize(new Dimension(190,40)); + buttonContainer.setOpaque(false); + + confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Guide_Tips_Know")); + confirmButton.setPreferredSize(new Dimension(78, 24)); + buttonContainer.add(confirmButton); + + contentPane.add(title); + contentPane.add(content1); + contentPane.add(content2); + contentPane.add(buttonContainer); + + this.add(contentPane, BorderLayout.CENTER); + } + + public void addConfirmAction(ActionListener listener) { + confirmButton.addActionListener(listener); + } + + public void removeConfirmAction(ActionListener listener) { + confirmButton.removeActionListener(listener); + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ExpandPane.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ExpandPane.java new file mode 100644 index 000000000..c71a15ea7 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ExpandPane.java @@ -0,0 +1,78 @@ +package com.fr.design.mainframe.guide.ui; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ExpandPane extends JPanel { + private static final Icon downIcon = IOUtils.readIcon("/com/fr/design/mainframe/guide/arrow_down.png"); + private static final Icon rightIcon = IOUtils.readIcon("/com/fr/design/mainframe/guide/arrow_right.png"); + private String title; + private boolean expand; + private UILabel arrow; + private JPanel headerPane; + private JPanel contentPane; + + public ExpandPane(String title, JPanel contentPane) { + this.title = title; + this.expand = true; + this.contentPane = contentPane; + initComponent(); + } + + private void initComponent() { + VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP, 10, 5); + layout.setAlignLeft(true); + this.setLayout(layout); + + JPanel headerPane = createHeader(); + this.add(headerPane); + this.add(contentPane); + headerPane.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + setExpand(!expand); + } + }); + } + + private JPanel createHeader() { + headerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + headerPane.setPreferredSize(new Dimension(200, 24)); + UILabel headerTitle = new UILabel(this.title); + headerTitle.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); + arrow = new UILabel(downIcon); + arrow.setOpaque(false); + arrow.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + headerPane.add(headerTitle, BorderLayout.CENTER); + headerPane.add(arrow, BorderLayout.WEST); + return headerPane; + } + + @Override + public void setPreferredSize(Dimension preferredSize) { + super.setPreferredSize(preferredSize); + headerPane.setPreferredSize(new Dimension(preferredSize.width, headerPane.getPreferredSize().height)); + contentPane.setPreferredSize(new Dimension(preferredSize.width, contentPane.getPreferredSize().height)); + } + + public void setExpand(boolean isExpand) { + this.expand = isExpand; + arrow.setIcon(isExpand ? downIcon : rightIcon); + contentPane.setVisible(isExpand); + } + + public boolean isExpand() { + return expand; + } +} + diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideCompleteDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideCompleteDialog.java new file mode 100644 index 000000000..29316652d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideCompleteDialog.java @@ -0,0 +1,134 @@ +package com.fr.design.mainframe.guide.ui; + +import com.fr.design.gui.frpane.UITextPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIButtonUI; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.utils.gui.GUIPaintUtils; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class GuideCompleteDialog extends JDialog { + private static final int DIALOG_WIDTH = 340; + private static final int DIALOG_HEIGHT = 367; + private static final Icon SUCCESS_ICON = IOUtils.readIcon("/com/fr/design/mainframe/guide/success.png"); + private static final int ICON_HEIGHT = 182; + private static final Color FONT_COLOR = new Color(51, 51, 52); + private static final Color BUTTON_BG_COLOR = new Color(65, 155,249); + private static GuideCompleteDialog dialog; + + public static GuideCompleteDialog getInstance() { + if (dialog == null) { + dialog = new GuideCompleteDialog(DesignerContext.getDesignerFrame()); + } + return dialog; + } + + private UITextPane textArea; + + public GuideCompleteDialog(Window window) { + super(window); + setSize(DIALOG_WIDTH, DIALOG_HEIGHT); + setUndecorated(true); + setModal(true); + setLocationRelativeTo(window); + this.setContentPane(getContentPane()); + } + + @Override + public Container getContentPane() { + JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + UILabel completeImage = new UILabel(SUCCESS_ICON); + completeImage.setPreferredSize(new Dimension(DIALOG_WIDTH, ICON_HEIGHT)); + + JPanel container = new JPanel(new BorderLayout(0, 10)); + container.setBorder(BorderFactory.createEmptyBorder(15, 52, 25, 52)); + + UILabel title = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Complete_Confirm")); + title.setFont(title.getFont().deriveFont(22.0f)); + title.setPreferredSize(new Dimension(190, 30)); + title.setHorizontalAlignment(SwingConstants.CENTER); + title.setForeground(FONT_COLOR); + + textArea = new UITextPane(); + textArea.setEnabled(false); + textArea.setOpaque(false); + textArea.setFont(textArea.getFont().deriveFont(18.0f)); + textArea.setPreferredSize(new Dimension(236, 52)); + textArea.setBorder(null); + textArea.setDisabledTextColor(FONT_COLOR); + StyledDocument doc = textArea.getStyledDocument(); + SimpleAttributeSet center = new SimpleAttributeSet(); + StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER); + doc.setParagraphAttributes(0, doc.getLength(), center, false); + + JPanel buttonContainer= FRGUIPaneFactory.createCenterFlowZeroGapBorderPane(); + buttonContainer.setPreferredSize(new Dimension(190,38)); + buttonContainer.setOpaque(false); + + UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Guide_Complete_End")){ + @Override + public Dimension getPreferredSize() { + return new Dimension(122, 38); + } + }; + button.setUI(confirmButtonUI); + button.setRoundBorder(true); + button.setForeground(Color.WHITE); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + dispose(); + } + }); + + buttonContainer.add(button); + container.add(title, BorderLayout.NORTH); + container.add(textArea, BorderLayout.CENTER); + container.add(buttonContainer,BorderLayout.SOUTH); + + contentPane.add(completeImage, BorderLayout.NORTH); + contentPane.add(container, BorderLayout.CENTER); + + return contentPane; + } + + public void showDialog(String str) { + textArea.setText(str); + repaint(); + this.setVisible(true); + } + + private UIButtonUI confirmButtonUI = new UIButtonUI() { + protected void doExtraPainting(UIButton b, Graphics2D g2d, int w, int h, String selectedRoles) { + if (isPressed(b) && b.isPressedPainted()) { + GUIPaintUtils.fillPressed(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), BUTTON_BG_COLOR); + } else if (isRollOver(b)) { + GUIPaintUtils.fillRollOver(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted(), BUTTON_BG_COLOR); + } else if (b.isNormalPainted()) { + GUIPaintUtils.fillNormal(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted(), BUTTON_BG_COLOR); + } + } + }; +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideLoadingGlassPane.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideLoadingGlassPane.java new file mode 100644 index 000000000..64017dfb7 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideLoadingGlassPane.java @@ -0,0 +1,53 @@ +package com.fr.design.mainframe.guide.ui; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; + +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +public class GuideLoadingGlassPane extends JPanel { + private static final String loadingImagePath = "/com/fr/design/mainframe/guide/loading.gif"; + private static GuideLoadingGlassPane loadingPane; + + public static GuideLoadingGlassPane getInstance() { + if (loadingPane == null) { + loadingPane = new GuideLoadingGlassPane(); + } + return loadingPane; + } + + public GuideLoadingGlassPane() { + this.setLayout(new GridBagLayout()); + this.setOpaque(false); + initComponent(); + } + + public void initComponent() { + JPanel loadingView = FRGUIPaneFactory.createBorderLayout_S_Pane(); + loadingView.setOpaque(false); + loadingView.setPreferredSize(new Dimension(130, 120)); + + JPanel imageContainer = FRGUIPaneFactory.createCenterFlowInnerContainer_S_Pane(); + imageContainer.setOpaque(false); + ImagePanel imagePanel = new ImagePanel(loadingImagePath); + imagePanel.setOpaque(false); + imagePanel.setPreferredSize(new Dimension(84, 84)); + imageContainer.add(imagePanel); + + UILabel hintLabel = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Loading_Wait")); + hintLabel.setHorizontalAlignment(SwingConstants.CENTER); + hintLabel.setForeground(Color.WHITE); + + loadingView.add(imageContainer, BorderLayout.NORTH); + loadingView.add(hintLabel, BorderLayout.SOUTH); + + this.add(loadingView, new GridBagConstraints()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideManageDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideManageDialog.java new file mode 100644 index 000000000..07059ad05 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideManageDialog.java @@ -0,0 +1,233 @@ +package com.fr.design.mainframe.guide.ui; + + +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.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.guide.base.Guide; +import com.fr.design.mainframe.guide.base.GuideGroup; +import com.fr.design.mainframe.guide.base.GuideManager; +import com.fr.design.mainframe.guide.base.GuideVersion; +import com.fr.design.mainframe.guide.collect.GuideCollector; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.border.Border; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class GuideManageDialog extends JDialog { + private static final int DEFAULT_HEIGHT = 400; + private static final int DEFAULT_WIDTH = 600; + private static final Icon GROUP_COMPLETE_NONE = IOUtils.readIcon("/com/fr/design/mainframe/guide/complete_none.png"); + private static final Icon GROUP_COMPLETE_SOME = IOUtils.readIcon("/com/fr/design/mainframe/guide/complete_some.png"); + private static final Icon GROUP_COMPLETE_ALL = IOUtils.readIcon("/com/fr/design/mainframe/guide/complete_all.png"); + private static final Color BORDER_COLOR = new Color(224, 224, 225); + private static final Color UNCOMPLETE_FONT_COLOR = new Color(51, 51, 52); + private static final Color COMPLETE_FONT_COLOR = new Color(51,51,52,128); + private static GuideManageDialog dialog; + + private JPanel scrollContent; + + public static GuideManageDialog getInstance() { + if (dialog == null) { + dialog = new GuideManageDialog(DesignerContext.getDesignerFrame()); + } + return dialog; + } + + public GuideManageDialog(Window parent) { + super(parent); + GuideCollector.getInstance().load(); + initComponent(); + } + + private void initComponent() { + this.setTitle(Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Title")); + setResizable(false); + setModal(true); + setLayout(FRGUIPaneFactory.createBorderLayout()); + setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); + GUICoreUtils.centerWindow(this); + JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + contentPane.add(createContentPanel(), BorderLayout.CENTER); + contentPane.add(createActionsPane(), BorderLayout.SOUTH); + setContentPane(contentPane); + } + + private UIScrollPane createContentPanel() { + scrollContent = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 5); + UIScrollPane scrollPane = new UIScrollPane(scrollContent); + return scrollPane; + } + + private JPanel createGuideVersionPane(GuideVersion guideVersion) { + JPanel expandContent = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 5); + for (GuideGroup guideGroup : guideVersion.getGuideGroupList()) { + JPanel guideGroupCard = createGuideGroupCard(guideGroup); + expandContent.add(guideGroupCard); + } + ExpandPane expandPane = new ExpandPane(Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Version_Title", guideVersion.getVersion()), expandContent); + return expandPane; + } + + + private JPanel createGuideGroupCard(GuideGroup guideGroup) { + JPanel card = FRGUIPaneFactory.createBorderLayout_S_Pane(); + card.setBorder(BorderFactory.createLineBorder(BORDER_COLOR)); + card.setBackground(Color.WHITE); + + JPanel cardContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); + cardContainer.setOpaque(false); + cardContainer.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + card.add(cardContainer, BorderLayout.CENTER); + + cardContainer.add(createGroupTitlePane(guideGroup), BorderLayout.NORTH); + cardContainer.add(createGroupContentPane(guideGroup), BorderLayout.CENTER); + return card; + } + + private JPanel createGroupTitlePane(GuideGroup guideGroup) { + JPanel titleContainer = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.CENTER, 0, 0); + titleContainer.setBorder(getBottomBorder()); + titleContainer.setOpaque(false); + + titleContainer.setPreferredSize(new Dimension(500, 40)); + JPanel titlePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(0, 8,0 ); + titlePane.setOpaque(false); + + UILabel iconLabel = new UILabel(getGroupStateIcon(guideGroup)); + iconLabel.setPreferredSize(new Dimension(16, 16)); + iconLabel.setOpaque(false); + + UILabel titleLabel = new UILabel(guideGroup.getName()); + titleLabel.setPreferredSize(new Dimension(200, 16)); + titleLabel.setForeground(new Color(65, 155, 249)); + titleLabel.setOpaque(false); + + titlePane.add(iconLabel); + titlePane.add(titleLabel); + titleContainer.add(titlePane); + return titleContainer; + } + + private JPanel createGroupContentPane(GuideGroup guideGroup) { + JPanel groupContainer = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 0); + groupContainer.setBorder(BorderFactory.createEmptyBorder(0,10,0,0)); + groupContainer.setOpaque(false); + for (int index = 0; index < guideGroup.getGuideList().size(); index++) { + JPanel guidePane = createGuidePane(guideGroup.getGuideList().get(index), index); + if (index != guideGroup.getGuideList().size() - 1) { + guidePane.setBorder(getBottomBorder()); + } + groupContainer.add(guidePane); + } + return groupContainer; + } + + + + private JPanel createGuidePane(Guide guide, int index) { + JPanel guidePaneContainer = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.CENTER, 0, 0); + guidePaneContainer.setPreferredSize(new Dimension(540, 40)); + guidePaneContainer.setOpaque(false); + + JPanel guidePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(0, 50,0 ); + guidePane.setOpaque(false); + + UILabel title = new UILabel((index + 1) + "、" + guide.getDescription()); + title.setPreferredSize(new Dimension(440, 20)); + title.setForeground(guide.isComplete() ? COMPLETE_FONT_COLOR : UNCOMPLETE_FONT_COLOR); + title.setOpaque(false); + + + UIButton button = new UIButton(guide.isComplete() ? Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Retry") : Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Show")); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + guide.go(); + } + }); + + button.setPreferredSize(new Dimension(48, 20)); + guidePane.add(title); + guidePane.add(button); + + guidePaneContainer.add(guidePane); + return guidePaneContainer; + } + + private Border getBottomBorder() { + return BorderFactory.createMatteBorder( + 0,0,1, 0, BORDER_COLOR + ); + } + + public void showDialog() { + resetScrollContent(); + this.setVisible(true); + } + + private Icon getGroupStateIcon(GuideGroup guideGroup) { + if (guideGroup.isCompleteAll()) { + return GROUP_COMPLETE_ALL; + } else if (guideGroup.isCompleteSome()) { + return GROUP_COMPLETE_SOME; + } else { + return GROUP_COMPLETE_NONE; + } + } + + private UIButton createCompleteAllButton() { + UIButton button = new UIButton(Toolkit.i18nText(Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Complete_All"))); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + GuideManager.getInstance().completeAll(); + resetScrollContent(); + } + }); + return button; + } + + private UIButton createCloseButton() { + UIButton button = new UIButton(Toolkit.i18nText(Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Close"))); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + } + }); + return button; + } + + private JPanel createActionsPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.setBorder(BorderFactory.createEmptyBorder(7, 10, 7, 10)); + container.add(createCompleteAllButton(), BorderLayout.WEST); + container.add(createCloseButton(), BorderLayout.EAST); + return container; + } + + private void resetScrollContent() { + scrollContent.removeAll(); + for (GuideVersion guideVersion : GuideManager.getInstance().getGuideVersionList()) { + scrollContent.add(createGuideVersionPane(guideVersion)); + } + revalidate(); + repaint(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ImagePanel.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ImagePanel.java new file mode 100644 index 000000000..deaf97417 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ImagePanel.java @@ -0,0 +1,28 @@ +package com.fr.design.mainframe.guide.ui; + +import javax.swing.JPanel; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Toolkit; + +/** + * Created by kerry on 2020-10-23 + */ +public class ImagePanel extends JPanel { + + + private Image image; + + public ImagePanel(String imagePath) { + image = Toolkit.getDefaultToolkit().createImage(ImagePanel.class + .getResource(imagePath)); + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + if (image != null) { + g.drawImage(image, 0, 0, getWidth(), getHeight(), this); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/Bubble.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/Bubble.java new file mode 100644 index 000000000..10b04362e --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/Bubble.java @@ -0,0 +1,152 @@ +package com.fr.design.mainframe.guide.ui.bubble; + +import javax.swing.JComponent; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +public class Bubble extends JComponent { + public enum TailDirection { + TOP, BOTTOM, LEFT, RIGHT + } + protected static final int TAIL_HEIGHT = 7; + protected static final int TAIL_WIDTH = 14; + protected static final int BUBBLE_WIDTH = 170; + protected static final Color BG_COLOR = new Color(240,240,241); + protected static final int BORDER_RADIUS = 10; + + + private TailDirection tailDirection; + private float tailStart; + + public Bubble() { + this(TailDirection.LEFT, 0.5f); + } + + public Bubble(TailDirection tailDirection, float tailStart) { + this.tailDirection = tailDirection; + this.tailStart = tailStart; + this.setOpaque(false); + } + + public void setTailDirection(TailDirection tailDirection) { + this.tailDirection = tailDirection; + } + + public TailDirection getTailDirection() { + return tailDirection; + } + + public void setTailStart(float tailStart) { + this.tailStart = tailStart; + } + + public float getTailStart() { + return tailStart; + } + + + @Override + public Dimension getPreferredSize() { + if (isPreferredSizeSet()) { + return super.getPreferredSize(); + } + return new Dimension(getDefaultWidth(), getDefaultHeight()); + + } + + protected int getDefaultWidth() { + return (isTailHorizontal() ? TAIL_HEIGHT : 0) + BUBBLE_WIDTH; + } + + protected int getDefaultHeight() { + return (isTailVertical() ? TAIL_HEIGHT : 0); + } + + @Override + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + Composite oldComposite = g2.getComposite(); + paintBubbleBg(g2); + g2.setComposite(oldComposite); + super.paintComponent(g); + } + + protected void paintBubbleBg(Graphics2D g2) { + g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); + paintRectBg(g2); + paintTailBg(g2); + } + + protected void paintRectBg(Graphics2D g2) { + g2.setColor(BG_COLOR); + Rectangle bounds = getRectBounds(); + g2.fillRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, BORDER_RADIUS, BORDER_RADIUS); + } + + protected void paintTailBg(Graphics2D g2) { + int width = getWidth(); + int height = getHeight(); + if (isTailVertical()) { + int tailX = (int) (width * tailStart); + int startX = Math.max(tailX - TAIL_WIDTH / 2, 0); + int endX = startX + TAIL_WIDTH; + int[] xPoints = {startX, endX, tailX}; + int[] yPoints = isTailTop() ? new int[]{TAIL_HEIGHT, TAIL_HEIGHT, 0} : new int[]{height - TAIL_HEIGHT, height - TAIL_HEIGHT, height}; + g2.fillPolygon(xPoints, yPoints, 3); + } else if (isTailHorizontal()) { + int tailY = (int) (height * tailStart); + int startY = Math.max(tailY - TAIL_WIDTH / 2, 0); + int endY = startY + TAIL_WIDTH; + int[] xPoints = isTailLeft() ? new int[]{TAIL_HEIGHT, TAIL_HEIGHT, 0} : new int[]{width - TAIL_HEIGHT, width - TAIL_HEIGHT, width}; + int[] yPoints = {startY, endY, tailY}; + g2.fillPolygon(xPoints, yPoints, 3); + } + } + + public Rectangle getRectBounds() { + int width = getWidth(); + int height = getHeight(); + switch (tailDirection) { + case TOP: + return new Rectangle(0, TAIL_HEIGHT, width, height - TAIL_HEIGHT); + case LEFT: + return new Rectangle(TAIL_HEIGHT, 0, width - TAIL_HEIGHT, height); + case RIGHT: + return new Rectangle(0, 0 , width - TAIL_HEIGHT, height); + case BOTTOM: + return new Rectangle(0, 0, width, height - TAIL_HEIGHT); + default: + return new Rectangle(0,0,0,0); + } + } + + public boolean isTailHorizontal() { + return isTailLeft() || isTailRight(); + } + + public boolean isTailVertical() { + return isTailTop() || isTailBottom(); + } + + public boolean isTailLeft() { + return tailDirection == TailDirection.LEFT; + } + + public boolean isTailRight() { + return tailDirection == TailDirection.RIGHT; + } + + public boolean isTailTop() { + return tailDirection == TailDirection.TOP; + } + + public boolean isTailBottom() { + return tailDirection == TailDirection.BOTTOM; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/BubbleWithClose.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/BubbleWithClose.java new file mode 100644 index 000000000..ba8f3da05 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/BubbleWithClose.java @@ -0,0 +1,267 @@ +package com.fr.design.mainframe.guide.ui.bubble; + + +import com.fr.base.GraphHelper; +import com.fr.design.gui.frpane.UITextPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.Icon; +import javax.swing.JTextPane; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Rectangle; +import java.awt.event.ActionListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.font.FontRenderContext; +import java.awt.font.LineBreakMeasurer; +import java.awt.font.TextAttribute; +import java.text.AttributedCharacterIterator; +import java.text.AttributedString; + +public class BubbleWithClose extends Bubble { + private static final Font FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 14); + private static final Icon ICON = IOUtils.readIcon("/com/fr/design/mainframe/guide/close.png"); + private static final int HEADER_HEIGHT = 24; + private static final Color HEADER_COLOR = new Color(245, 245, 246); + private static final Color TITLE_COLOR = new Color(51, 51, 52); + private static final Color CONTENT_COLOR = new Color(51,51,52,128); + private static final Insets DEFAULT_INSET = new Insets(10, 15, 10, 15); + + + private String title; + private String content; + private UITextPane titleTextArea; + private UITextPane contentTextArea; + private UIButton closeButton; + + public BubbleWithClose(String title, String content) { + this(title, content, TailDirection.LEFT, 0.5f); + } + + public BubbleWithClose(String title, String content, TailDirection tailDirection, float tailStart) { + super(tailDirection, tailStart); + this.title = title; + this.content = content; + this.initComponent(); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + protected void initComponent() { + this.setLayout(getLayoutManager()); + createCloseButton(); + createContentPane(); + this.addComponentListener(new ComponentAdapter() { + @Override + public void componentShown(ComponentEvent e) { + super.componentShown(e); + } + + @Override + public void componentResized(ComponentEvent e) { + Rectangle rectBounds = getRectBounds(); + Dimension buttonSize = closeButton.getPreferredSize(); + + closeButton.setBounds(getWidth() - 10 - buttonSize.width, rectBounds.y + (HEADER_HEIGHT - buttonSize.height) / 2, buttonSize.width, buttonSize.height); + + Dimension titleSize = new Dimension(0,0); + Dimension contentSize = new Dimension(0, 0); + if (titleTextArea != null) { + titleSize = calTextSize(titleTextArea, getTextAreaMaxWidth()); + int x = rectBounds.x + (rectBounds.width - getHorizontalInsets() - titleSize.width) / 2 + DEFAULT_INSET.left; + int y = rectBounds.y + HEADER_HEIGHT + DEFAULT_INSET.top; + titleTextArea.setBounds(x, y, titleSize.width, titleSize.height); + } + + if (contentTextArea != null) { + contentSize = calTextSize(contentTextArea, getTextAreaMaxWidth()); + int x = rectBounds.x + (rectBounds.width - getHorizontalInsets() - contentSize.width) / 2 + DEFAULT_INSET.left; + int y = rectBounds.y = HEADER_HEIGHT + DEFAULT_INSET.top + (titleSize.height == 0 ? 0 : titleSize.height + 10); + contentTextArea.setBounds(x,y, contentSize.width, contentSize.height); + } + setSize(getPreferredSize().width, getPreferredSize().height); + repaint(); + } + }); + } + + private void createCloseButton() { + closeButton = new UIButton(); + closeButton.setIcon(ICON); + closeButton.set4ToolbarButton(); + closeButton.setPreferredSize(new Dimension(12, 12)); + closeButton.setRolloverEnabled(false); + closeButton.setPressedPainted(false); + this.add(closeButton); + } + + public void addCloseActionListener(ActionListener actionListener) { + closeButton.addActionListener(actionListener); + + } + + public void removeCloseActionListener(ActionListener actionListener){ + closeButton.removeActionListener(actionListener); + } + + private void createContentPane() { + createTitleTextArea(); + createContentTextArea(); + } + + private void createTitleTextArea() { + if (StringUtils.isNotEmpty(title)) { + titleTextArea = createTextArea(title, FONT, TITLE_COLOR); + this.add(titleTextArea); + } + + } + + private void createContentTextArea() { + if (StringUtils.isNotEmpty(content)) { + contentTextArea = createTextArea(content, FONT, CONTENT_COLOR); + this.add(contentTextArea); + } + } + + private UITextPane createTextArea(String str, Font font, Color foreground) { + UITextPane textArea= new UITextPane(){ + @Override + public Insets getInsets() { + return new Insets(0, 0, 0, 0); + } + }; + textArea.setText(str); + textArea.setEnabled(false); + textArea.setDisabledTextColor(foreground); + textArea.setBorder(null); + textArea.setFont(font); + textArea.setOpaque(false); + textArea.setForeground(foreground); + StyledDocument doc = textArea.getStyledDocument(); + SimpleAttributeSet center = new SimpleAttributeSet(); + StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER); + doc.setParagraphAttributes(0, doc.getLength(), center, false); + return textArea; + } + + protected int getDefaultHeight() { + Dimension titleSize = calTextSize(titleTextArea, getDefaultTextAreaMaxWidth()); + Dimension contentSize = calTextSize(contentTextArea, getDefaultTextAreaMaxWidth()); + return (isTailVertical() ? TAIL_HEIGHT : 0) + HEADER_HEIGHT + titleSize.height + (titleSize.height == 0 ? 0 : 5) + contentSize.height + getVerticalInsets(); + } + + private LayoutManager getLayoutManager() { + return new LayoutManager() { + @Override + public void addLayoutComponent(String name, Component comp) { + } + + @Override + public void removeLayoutComponent(Component comp) { + + } + + @Override + public Dimension preferredLayoutSize(Container parent) { + return parent.getPreferredSize(); + } + + @Override + public Dimension minimumLayoutSize(Container parent) { + return null; + } + + @Override + public void layoutContainer(Container parent) { + + } + }; + } + + @Override + protected void paintBubbleBg(Graphics2D g2) { + super.paintBubbleBg(g2); + paintHeaderBg(g2); + } + + private void paintHeaderBg(Graphics2D g2) { + g2.setColor(HEADER_COLOR); + Rectangle bounds = getRectBounds(); + g2.fillRoundRect(bounds.x, bounds.y, bounds.width, HEADER_HEIGHT, 10, 10); + } + + private int countLines(JTextPane textArea, int max_width) { + AttributedString text = new AttributedString(textArea.getText()); + text.addAttribute(TextAttribute.FONT, textArea.getFont()); + FontRenderContext frc = textArea.getFontMetrics(textArea.getFont()) + .getFontRenderContext(); + AttributedCharacterIterator charIt = text.getIterator(); + LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(charIt, frc); + lineMeasurer.setPosition(charIt.getBeginIndex()); + int lines = 0; + while (lineMeasurer.getPosition() < charIt.getEndIndex()) { + lineMeasurer.nextLayout(max_width); + lines++; + } + return lines; + } + + private Dimension calTextSize(JTextPane textArea, int maxWidth) { + if (textArea == null) { + return new Dimension(0, 0); + } + FontMetrics fontMetrics = GraphHelper.getFontMetrics(textArea.getFont()); + int line = countLines(textArea, maxWidth); + int width = maxWidth; + if (line == 1) { + width = fontMetrics.stringWidth(textArea.getText()); + } + int height = fontMetrics.getHeight() * line; + return new Dimension(width, height); + } + + private int getTextAreaMaxWidth() { + return getWidth() - (isTailHorizontal() ? TAIL_HEIGHT : 0) -getHorizontalInsets(); + } + + private int getDefaultTextAreaMaxWidth() { + return BUBBLE_WIDTH - getHorizontalInsets(); + } + + private int getHorizontalInsets() { + return DEFAULT_INSET.left + DEFAULT_INSET.right; + } + + private int getVerticalInsets() { + return DEFAULT_INSET.top + DEFAULT_INSET.bottom; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/utils/ScreenImage.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/utils/ScreenImage.java new file mode 100644 index 000000000..8705d0e8a --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/utils/ScreenImage.java @@ -0,0 +1,98 @@ +package com.fr.design.mainframe.guide.utils; + +import javax.swing.JComponent; +import javax.swing.SwingUtilities; +import java.awt.AWTException; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; + +public class ScreenImage { + + public static BufferedImage createImage(JComponent component) { + return ScreenImage.createImage(component, getRegion(component)); + } + + public static BufferedImage createImage(JComponent component, Rectangle region) { + if (! component.isDisplayable()) { + Dimension d = component.getSize(); + + if (d.width == 0 || d.height == 0) { + d = component.getPreferredSize(); + component.setSize( d ); + } + + layoutComponent( component ); + } + + BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = image.createGraphics(); + + if (! component.isOpaque()) { + g2d.setColor( component.getBackground() ); + g2d.fillRect(region.x, region.y, region.width, region.height); + } + + g2d.translate(-region.x, -region.y); + component.print( g2d ); + g2d.dispose(); + return image; + } + + public static BufferedImage createImage(Component component) + throws AWTException { + Point p = new Point(0, 0); + SwingUtilities.convertPointToScreen(p, component); + Rectangle region = component.getBounds(); + region.x = p.x; + region.y = p.y; + return ScreenImage.createImage(region); + } + + public static BufferedImage createImageWithModal(JComponent component) { + Rectangle region = getRegion(component); + BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = image.createGraphics(); + g2d.drawImage(createImage(component), 0, 0, null); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f)); + g2d.setColor(Color.BLACK); + g2d.fillRect(0, 0, region.width, region.height); + g2d.dispose(); + return image; + } + + public static BufferedImage createImage(Rectangle region) + throws AWTException { + BufferedImage image = new Robot().createScreenCapture( region ); + return image; + } + + private static Rectangle getRegion(Component component) { + Dimension d = component.getSize(); + if (d.width == 0 || d.height == 0) { + d = component.getPreferredSize(); + component.setSize( d ); + } + return new Rectangle(0, 0, d.width, d.height); + } + + static void layoutComponent(Component component) { + synchronized (component.getTreeLock()) { + component.doLayout(); + + if (component instanceof Container) { + for (Component child : ((Container)component).getComponents()) { + layoutComponent(child); + } + } + } + } + +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java index f34f8a27f..798bb73c5 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java @@ -36,46 +36,56 @@ public class FormThemeProfilePane extends TemplateThemeProfilePane { } @Override - protected JPanel createCustomEditorsPane() { - JPanel container = super.createCustomEditorsPane(); - formBodyStyleSettingPane = new FormBodyStyleEditPane(); - addCustomEditorPane(i18nText("Fine-Design_Predefined_Template_Background"), formBodyStyleSettingPane); - - addCustomEditorPane(i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane()); - addCustomEditorPane(i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane()); - - - componentStyleSettingPane = new ComponentStyleEditPane(); - addCustomEditorPane(i18nText("Fine-Design_Predefined_Component_Style"), componentStyleSettingPane); - return container; + public TemplateThemeEditorPane createThemeEditorPane() { + return new FormThemeEditorPane(config); } @Override - protected JPanel createChartStyleSettingPane() { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - chartStyleSettingPane = new ChartStyleFormEditPane(); - container.add(chartStyleSettingPane); - return container; + public String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Form_Theme_Profile_Dialog_Title"); } - @Override - public void populateBean4CustomEditors(FormTheme theme) { - super.populateBean4CustomEditors(theme); - formBodyStyleSettingPane.populateBean(theme.getBodyStyle()); - componentStyleSettingPane.populateBean(theme.getComponentStyle()); - } + private static class FormThemeEditorPane extends TemplateThemeEditorPane { - @Override - public void updateBean(FormTheme theme) { - ThemedFormBodyStyle formBodyStyle = formBodyStyleSettingPane.updateBean(); - theme.setBodyStyle(formBodyStyle); + private final FormBodyStyleEditPane formBodyStyleSettingPane; + private final ComponentStyleEditPane componentStyleSettingPane; - ThemedComponentStyle componentStyle = componentStyleSettingPane.updateBean(); - theme.setComponentStyle(componentStyle); - } + public FormThemeEditorPane(TemplateThemeConfig config) { + super(config); + formBodyStyleSettingPane = new FormBodyStyleEditPane(); + addCustomEditorPane(i18nText("Fine-Design_Predefined_Template_Background"), formBodyStyleSettingPane); - @Override - public String title4PopupWindow() { - return Toolkit.i18nText("Fine-Design_Basic_Form_Theme_Profile_Dialog_Title"); + addCustomEditorPane(i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane()); + addCustomEditorPane(i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane()); + + + componentStyleSettingPane = new ComponentStyleEditPane(); + addCustomEditorPane(i18nText("Fine-Design_Predefined_Component_Style"), componentStyleSettingPane); + } + + @Override + protected JPanel createChartStyleSettingPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + chartStyleSettingPane = new ChartStyleFormEditPane(); + container.add(chartStyleSettingPane); + return container; + } + + @Override + protected void populateBean4CustomEditors(FormTheme theme) { + super.populateBean4CustomEditors(theme); + formBodyStyleSettingPane.populateBean(theme.getBodyStyle()); + componentStyleSettingPane.populateBean(theme.getComponentStyle()); + } + + @Override + protected void updateBean4CustomEditors(FormTheme theme) { + super.updateBean4CustomEditors(theme); + ThemedFormBodyStyle formBodyStyle = formBodyStyleSettingPane.updateBean(); + theme.setBodyStyle(formBodyStyle); + + ThemedComponentStyle componentStyle = componentStyleSettingPane.updateBean(); + theme.setComponentStyle(componentStyle); + } } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java index 1158a8eb5..f0f25f677 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java @@ -25,28 +25,37 @@ public class ReportThemeProfilePane extends TemplateThemeProfilePane createThemeEditorPane() { + return new ReportThemeEditorPane(config); } @Override public String title4PopupWindow() { return Toolkit.i18nText("Fine-Design_Basic_Report_Theme_Profile_Dialog_Title"); } + + private static class ReportThemeEditorPane extends TemplateThemeEditorPane { + + private final ReportBodyStyleEditPane reportBodyStyleSettingPane; + + public ReportThemeEditorPane(TemplateThemeConfig config) { + super(config); + this.reportBodyStyleSettingPane = new ReportBodyStyleEditPane(); + addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Template_Background"), reportBodyStyleSettingPane); + addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane()); + addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane()); + } + + @Override + public void populateBean4CustomEditors(ReportTheme theme) { + super.populateBean4CustomEditors(theme); + reportBodyStyleSettingPane.populateBean(theme.getBodyStyle()); + } + + @Override + public void updateBean4CustomEditors(ReportTheme theme) { + super.updateBean4CustomEditors(theme); + theme.setBodyStyle(this.reportBodyStyleSettingPane.updateBean()); + } + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java index 543df64eb..ea649033e 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java @@ -64,6 +64,7 @@ public class TemplateThemeBlock extends JPanel { TemplateThemeConfig config, TemplateThemeProfilePane profilePane) { this.name = name; + this.setName(name); this.displayTheme4NewTemplateMarker = displayTheme4NewTemplateMarker; this.config = config; this.profilePane = profilePane; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java new file mode 100644 index 000000000..c2e28332d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java @@ -0,0 +1,297 @@ +package com.fr.design.mainframe.theme; + +import com.fr.base.theme.FineColorFlushUtils; +import com.fr.base.theme.FineColorManager; +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; +import com.fr.base.theme.settings.ThemedCellStyleList; +import com.fr.base.theme.settings.ThemedColorScheme; +import com.fr.design.designer.IntervalConstants; +import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; +import com.fr.design.gui.frpane.AttributeChangeListener; +import com.fr.design.gui.frpane.UITabbedPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.theme.edit.CellStyleListEditPane; +import com.fr.design.mainframe.theme.edit.ChartStyleEditPane; +import com.fr.design.mainframe.theme.edit.ui.ColorListExtendedPane; +import com.fr.design.mainframe.theme.edit.ui.ColorListPane; +import com.fr.design.mainframe.theme.edit.ui.LabelUtils; +import com.fr.design.mainframe.theme.ui.AutoCheckTextField; +import com.fr.design.mainframe.theme.ui.AutoCheckThemeNameTextField; +import com.fr.design.mainframe.theme.ui.BorderUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.util.List; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/8/13 + */ +public abstract class TemplateThemeEditorPane extends JPanel { + public static final int LEFT_TITLE_PANE_HEIGHT = 539; + + public static final int RIGHT_PANE_WIDTH = 362; + public static final int RIGHT_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT; + + protected AutoCheckThemeNameTextField nameTextField; + private UILabel nameErrorLabel; + protected ColorListPane colorListPane; + protected CellStyleListEditPane cellStyleSettingPane; + protected ChartStyleEditPane chartStyleSettingPane; + + protected boolean isPopulating = false; + protected UITabbedPane uiTabbedPane; + + private final TemplateThemeConfig config; + + private boolean refreshingThemedColor = false; + private T theme; + + private AttributeChangeListener changeListener; + private AutoCheckTextField.CheckListener themeNameCheckListener; + + public TemplateThemeEditorPane(TemplateThemeConfig config) { + super(); + this.config = config; + theme = config.createNewTheme(); + initializePane(); + } + + private void initializePane() { + setLayout(new BorderLayout(0, 0)); + setPreferredSize(new Dimension(RIGHT_PANE_WIDTH, RIGHT_PANE_HEIGHT)); + JPanel nameEditPane = createNameEditPane(); + add(nameEditPane, BorderLayout.NORTH); + + JPanel settingPane = new JPanel(new BorderLayout(0, IntervalConstants.INTERVAL_L1)); + settingPane.add(createColorSchemeEditPane(), BorderLayout.NORTH); + settingPane.add(createCustomEditorsPane(), BorderLayout.CENTER); + + add(settingPane, BorderLayout.CENTER); + } + + private JPanel createNameEditPane() { + nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED); + nameErrorLabel.setVisible(false); + + nameTextField = new AutoCheckThemeNameTextField<>(); + nameTextField.setThemeConfig(config); + nameTextField.setEditable(false); + nameTextField.setEnabled(false); + nameTextField.setPreferredSize(new Dimension(165, 20)); + nameTextField.setNameCheckListener(new AutoCheckTextField.CheckListener() { + @Override + public void onChecked(String error, boolean valid) { + nameErrorLabel.setVisible(StringUtils.isNotEmpty(error)); + nameErrorLabel.setText(error); + + themeNameCheckListener.onChecked(error, valid); + } + }); + + double p = TableLayout.PREFERRED; + + JPanel container = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{ + new Component[] { LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Name")), nameTextField }, + new Component[] { null, nameErrorLabel }, + }, new double[] { 20, 20}, new double[] { p, 165}, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_W0); + + container.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + return container; + } + + private JPanel createColorSchemeEditPane() { + colorListPane = new ColorListPane(); + + double p = TableLayout.PREFERRED; + double[] rowSize = new double[]{p, p, p}; + double[] columnSize = {p, p}; + + JPanel colorListContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + colorListContainerPane.add(colorListPane, BorderLayout.WEST); + + UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Tip"), new Color(153, 153, 153)); + + JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ + {LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Label")), colorListContainerPane}, + {null, tipLabel}, + }, + rowSize, columnSize, 18, 7); + content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + JPanel borderContainer = new JPanel(new BorderLayout()); + borderContainer.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Title"))); + borderContainer.add(content); + + JPanel container = new JPanel(new BorderLayout()); + container.add(borderContainer, BorderLayout.CENTER); + + colorListPane.addColorChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + if (refreshingThemedColor) { + return; + } + List colors = colorListPane.update(); + refreshingThemedColor = true; + onColorSchemeChanged(colors); + refreshingThemedColor = false; + + fireAttributeChange(); + } + }); + + return container; + } + private void onColorSchemeChanged(List colors) { + FineColorManager.FineColorReplaceByColorScheme replaceByColorScheme = new FineColorManager.FineColorReplaceByColorScheme(colors); + T theme = updateBean(); + FineColorFlushUtils.replaceCacheObject(theme, replaceByColorScheme); + FineColorManager.traverse(theme, replaceByColorScheme); + populateBean4CustomEditors(theme); + //图表渐变色 + chartStyleSettingPane.populateGradientBar(colors); + this.repaint(); + } + + protected JPanel createCustomEditorsPane() { + JPanel container = new JPanel(new BorderLayout()); + container.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Custom_Settings_Title"))); + + uiTabbedPane = new UITabbedPane(); + uiTabbedPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 1)); + container.add(uiTabbedPane, BorderLayout.CENTER); + + return container; + } + + public void addCustomEditorPane(String title, final Component component) { + AbstractAttrNoScrollPane settingPane = new NoBorderAbstractAttrNoScrollPane() { + @Override + protected JPanel createContentPane() { + JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + contentPane.add(component, BorderLayout.CENTER); + return contentPane; + } + }; + settingPane.addAttributeChangeListener(new AttributeChangeListener() { + @Override + public void attributeChange() { + fireAttributeChange(); + } + }); + uiTabbedPane.addTab(title, settingPane); + } + protected JPanel createCellStyleSettingPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + cellStyleSettingPane = new CellStyleListEditPane(); + cellStyleSettingPane.registerAttrChangeListener(new AttributeChangeListener() { + @Override + public void attributeChange() { + fireAttributeChange(); + } + }); + container.add(cellStyleSettingPane); + return container; + } + protected JPanel createChartStyleSettingPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + chartStyleSettingPane = new ChartStyleEditPane(); + container.add(chartStyleSettingPane); + return container; + } + + public void populateBean(T theme) { + this.theme = theme; + isPopulating = true; + + String name = theme.getName(); + setThemeNameEditable(StringUtils.isEmpty(name)); + + nameTextField.setText(name); + + colorListPane.populate(theme.getColorScheme().getColors()); + + populateBean4CustomEditors(theme); + isPopulating = false; + } + + protected void populateBean4CustomEditors(T theme) { + cellStyleSettingPane.populateBean(theme.getCellStyleList()); + chartStyleSettingPane.populateBean(theme.getChartStyle()); + } + + public T updateBean() { + if (theme == null) { + theme = config.createNewTheme(); + } + + theme.setName(this.nameTextField.getText()); + + ThemedColorScheme colorScheme = theme.getColorScheme(); + colorScheme.setColors(this.colorListPane.update()); + theme.setColorScheme(colorScheme); + + updateBean4CustomEditors(theme); + + return theme; + } + + protected void updateBean4CustomEditors(T theme) { + ThemedCellStyleList cellStyleConfig = this.cellStyleSettingPane.updateBean(); + theme.setCellStyleList(cellStyleConfig); + + theme.setChartStyle(this.chartStyleSettingPane.updateBean()); + } + + public void setThemeNameEditable(boolean editable) { + nameTextField.setEditable(editable); + nameTextField.setEnabled(editable); + } + + public boolean checkNameValid() { + return nameTextField.checkValid(); + } + + public List getCurrentColorScheme() { + return colorListPane.update(); + } + + private void fireAttributeChange() { + if (!isPopulating && !refreshingThemedColor && changeListener != null) { + changeListener.attributeChange(); + } + } + + public void addAttributeChangeListener(AttributeChangeListener changeListener) { + this.changeListener = changeListener; + } + public void addThemeNameCheckListener(AutoCheckTextField.CheckListener checkListener) { + this.themeNameCheckListener = checkListener; + } + + private static abstract class NoBorderAbstractAttrNoScrollPane extends AbstractAttrNoScrollPane { + @Override + protected void initContentPane() { + super.initContentPane(); + if (leftContentPane != null) { + // 修正 AbstractAttrNoScrollPane 的默认行为 + leftContentPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + } + } + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridControlPane.java similarity index 91% rename from designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java rename to designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridControlPane.java index be9dec160..6e04cb06f 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridControlPane.java @@ -51,34 +51,34 @@ import static com.fr.design.i18n.Toolkit.i18nText; * @version 1.0 * Created by Starryi on 2021/8/13 */ -public class TemplateThemeManagePane extends BasicPane { - public static final int CONTENT_WIDTH = TemplateThemeListPane.CONTENT_WIDTH + 10; - public static final int CONTENT_HEIGHT = TemplateThemeListPane.CONTENT_HEIGHT + 37; +public class TemplateThemeGridControlPane extends BasicPane { + public static final int CONTENT_WIDTH = TemplateThemeGridPane.CONTENT_WIDTH + 10; + public static final int CONTENT_HEIGHT = TemplateThemeGridPane.CONTENT_HEIGHT + 37; private final RemoveThemeAction removeAction; private final UIButton setTheme4NewTemplateButton; private final TemplateThemeConfig config; - private final TemplateThemeListPane themeListPane; + private final TemplateThemeGridPane themeListPane; private final TemplateThemeProfilePane profilePane; private final AsyncThemeFetcher asyncThemeFetcher; - public static TemplateThemeManagePane createFormThemesManagerPane() { + public static TemplateThemeGridControlPane createFormThemesManagerPane() { FormThemeConfig config = FormThemeConfig.getInstance(); FormThemeProfilePane editPane = new FormThemeProfilePane(config); - return new TemplateThemeManagePane<>(config, editPane); + return new TemplateThemeGridControlPane<>(config, editPane); } - public static TemplateThemeManagePane createReportThemesManagerPane() { + public static TemplateThemeGridControlPane createReportThemesManagerPane() { ReportThemeConfig config = ReportThemeConfig.getInstance(); ReportThemeProfilePane editPane = new ReportThemeProfilePane(config); - return new TemplateThemeManagePane<>(config, editPane); + return new TemplateThemeGridControlPane<>(config, editPane); } - public TemplateThemeManagePane(TemplateThemeConfig config, TemplateThemeProfilePane profilePane) { + public TemplateThemeGridControlPane(TemplateThemeConfig config, TemplateThemeProfilePane profilePane) { this.config = config; this.profilePane = profilePane; - this.themeListPane = new TemplateThemeListPane<>(true, config, profilePane); + this.themeListPane = new TemplateThemeGridPane<>(true, config, profilePane); this.removeAction = new RemoveThemeAction(false); this.setTheme4NewTemplateButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Default_Setting")); this.asyncThemeFetcher = new AsyncThemeFetcher<>(1, config); @@ -179,7 +179,7 @@ public class TemplateThemeManagePane extends BasicPane @Override public void afterRollback() { super.afterRollback(); - FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this), + FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this), i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE); @@ -225,11 +225,11 @@ public class TemplateThemeManagePane extends BasicPane @Override public void actionPerformed(ActionEvent e) { - T theme = TemplateThemeManagePane.this.themeListPane.getSelectedTheme(); + T theme = TemplateThemeGridControlPane.this.themeListPane.getSelectedTheme(); if (theme == null) { return; } - int result = FineJOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this), + int result = FineJOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Delete_Tip", theme.getName()), Toolkit.i18nText("Fine-Design_Basic_Delete"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); if (result == JOptionPane.YES_OPTION) { @@ -237,7 +237,7 @@ public class TemplateThemeManagePane extends BasicPane @Override public void afterRollback() { super.afterRollback(); - FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this), + FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this), i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE); @@ -269,7 +269,7 @@ public class TemplateThemeManagePane extends BasicPane } private void createNewTheme(T prototypeTheme) { - Window parent = SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this); + Window parent = SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this); TemplateThemeProfileDialog profileDialog = new TemplateThemeProfileDialog<>(parent, profilePane); try { T theme = (T) prototypeTheme.clone(); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPagesPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPagesPane.java new file mode 100644 index 000000000..855e2bf78 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPagesPane.java @@ -0,0 +1,341 @@ +package com.fr.design.mainframe.theme; + +import com.fr.base.ScreenResolution; +import com.fr.base.theme.FormTheme; +import com.fr.base.theme.FormThemeConfig; +import com.fr.base.theme.ReportTheme; +import com.fr.base.theme.ReportThemeConfig; +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; +import com.fr.design.ExtraDesignClassManager; +import com.fr.design.dialog.BasicPane; +import com.fr.design.event.ChangeEvent; +import com.fr.design.event.ChangeListener; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.gui.frpane.UITabbedPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.theme.dialog.TemplateThemeDialog; +import com.fr.design.mainframe.theme.provider.ThemeManageActionProvider; +import com.fr.design.mainframe.theme.ui.BreadcrumbBar; +import com.fr.stable.ArrayUtils; +import com.fr.stable.unit.FU; +import com.fr.workspace.WorkContext; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.border.CompoundBorder; +import javax.swing.border.LineBorder; +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.Stroke; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/10/9 + */ +public class TemplateThemeGridPagesPane extends JPanel { + public static final String COMPLETE_BUTTON = "theme_button_complete"; + private BreadcrumbBar breadcrumbBar; + private JPanel contentPane; + private CardLayout cardLayout; + + private TemplateThemeGridPagePane themeUsingPane; + private TemplateThemeGridPagePane themeManagingPane; + + private PageChangeListener pageChangeListener; + private TemplateThemeGridPagePane currentTemplateThemeGridPagePane; + + public TemplateThemeGridPagesPane() { + initializePane(); + } + + private void initializePane() { + setLayout(new BorderLayout()); + setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); + + breadcrumbBar = new BreadcrumbBar(); + breadcrumbBar.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); + add(breadcrumbBar, BorderLayout.NORTH); + + contentPane = new JPanel(); + contentPane.setBorder(new CompoundBorder( + new TopLineBorder(new Color(0xE0E0E1), 1), + BorderFactory.createEmptyBorder(10, 0, 0, 0))); + cardLayout = new CardLayout(); + contentPane.setLayout(cardLayout); + add(contentPane, BorderLayout.CENTER); + + + themeUsingPane = new TemplateThemeUsingPane(); + contentPane.add(themeUsingPane, themeUsingPane.getTitle()); + themeManagingPane = new TemplateThemeManagingPane(); + contentPane.add(themeManagingPane, themeManagingPane.getTitle()); + + showThemeUsingPane(); + } + + public void showThemeUsingPane() { + if (currentTemplateThemeGridPagePane != themeUsingPane) { + cardLayout.show(contentPane, themeUsingPane.getTitle()); + currentTemplateThemeGridPagePane = themeUsingPane; + if (pageChangeListener != null) { + pageChangeListener.onPageChangeListener(); + } + breadcrumbBar.clear(); + breadcrumbBar.addCrumb(themeUsingPane.getTitle(), new BreadcrumbBar.BreadcrumbBackListener() { + @Override + public void onBreadcrumbBack(String text) { + cardLayout.show(contentPane, themeUsingPane.getTitle()); + currentTemplateThemeGridPagePane = themeUsingPane; + if (pageChangeListener != null) { + pageChangeListener.onPageChangeListener(); + } + } + }); + } + } + + public void showThemeManagingPane() { + if (currentTemplateThemeGridPagePane != themeManagingPane) { + cardLayout.show(contentPane, themeManagingPane.getTitle()); + currentTemplateThemeGridPagePane = themeManagingPane; + if (pageChangeListener != null) { + pageChangeListener.onPageChangeListener(); + } + breadcrumbBar.addCrumb(themeManagingPane.getTitle(), null); + } + } + + public UIButton[] createLeftButtons() { + UIButton[] buttons = new UIButton[] {}; + if (currentTemplateThemeGridPagePane != themeManagingPane && WorkContext.getCurrent().isRoot()) { + buttons = ArrayUtils.addAll(buttons, createOpenThemeManagerButton()); + } + return buttons; + } + + public UIButton[] createRightButtons() { + UIButton[] buttons = new UIButton[] {}; + buttons = ArrayUtils.addAll(buttons, createExtraButtons()); + buttons = ArrayUtils.addAll(buttons, createCompleteButton()); + return buttons; + } + + private UIButton createOpenThemeManagerButton() { + UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title")); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + showThemeManagingPane(); + } + }); + return button; + } + + private UIButton[] createExtraButtons() { + List uiButtonList = new ArrayList<>(); + + Set providers = ExtraDesignClassManager.getInstance().getArray(ThemeManageActionProvider.MARK_STRING); + for (ThemeManageActionProvider provider : providers) { + uiButtonList.add(provider.createButton(new ThemeManageActionProvider.ThemeManageActionContext() { + + @Override + public TemplateThemeDialog getDialog() { + Container container = getRootPane().getParent(); + if (container instanceof TemplateThemeDialog) { + return (TemplateThemeDialog) container; + } + return null; + } + + @Override + public TemplateThemeConfig getConfig() { + return currentTemplateThemeGridPagePane.getConfig(); + } + })); + } + + return uiButtonList.toArray(new UIButton[]{}); + } + + private UIButton createCompleteButton() { + UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Complete")); + button.setName(COMPLETE_BUTTON); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Container container = getRootPane().getParent(); + if (container instanceof TemplateThemeDialog) { + ((TemplateThemeDialog) container).exit(); + } + } + }); + return button; + } + + public void exit() { + themeUsingPane.exit(); + themeManagingPane.exit(); + } + + public void setPageChangeListener(PageChangeListener changeListener) { + this.pageChangeListener = changeListener; + } + + public interface PageChangeListener { + void onPageChangeListener(); + } + + public static class TopLineBorder extends LineBorder { + private final FU fu; + + private TopLineBorder(Color color, int thickness) { + super(color, thickness); + fu = FU.getInstance(thickness); + } + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + Graphics2D g2d = (Graphics2D)g; + + Color oldColor = g2d.getColor(); + Stroke oldStroke = g2d.getStroke(); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g2d.setColor(getLineColor()); + int thickness = Math.max(1, fu.toPixI(ScreenResolution.getScreenResolution())); + g2d.setStroke(new BasicStroke(thickness)); + g2d.drawLine(0, 0, width, thickness); + + g2d.setStroke(oldStroke); + g2d.setColor(oldColor); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + } + } + + public abstract static class TemplateThemeGridPagePane extends BasicPane { + public abstract TemplateThemeConfig getConfig(); + + public void exit() { } + } + + public static class TemplateThemeUsingPane extends TemplateThemeGridPagePane { + private final JTemplate template; + public final TemplateThemeGridPane themeListPane; + + public TemplateThemeUsingPane() { + super(); + setLayout(new BorderLayout()); + setBorder(new CompoundBorder( + BorderFactory.createLineBorder(new Color(0xE0E0E1)), + BorderFactory.createEmptyBorder(0, 10, 0, 10))); + + template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + TemplateThemeConfig config = template.getUsingTemplateThemeConfig(); + themeListPane = new TemplateThemeGridPane<>(false, config, null); + + themeListPane.startListenThemeConfig(); + + themeListPane.setSelectedChangeListener(new ChangeListener() { + @Override + public void fireChanged(ChangeEvent event) { + TemplateTheme theme = themeListPane.getSelectedTheme(); + if (theme != null) { + template.setTemplateTheme(theme); + themeListPane.repaint(); + } + } + }); + + add(themeListPane, BorderLayout.CENTER); + } + + @Override + public TemplateThemeConfig getConfig() { + return template.getUsingTemplateThemeConfig(); + } + + @Override + public void exit() { + themeListPane.stopListenThemeConfig(); + themeListPane.stopAsyncFetchTheme(); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"); + } + } + + public static class TemplateThemeManagingPane extends TemplateThemeGridPagePane { + public static final int CONTENT_WIDTH = TemplateThemeGridControlPane.CONTENT_WIDTH + 4; + public static final int CONTENT_HEIGHT = TemplateThemeGridControlPane.CONTENT_HEIGHT + 10; + + private final UITabbedPane tabbedPane; + private final TemplateThemeGridControlPane formThemesManagerPane; + private final TemplateThemeGridControlPane reportThemesManagerPane; + + public TemplateThemeManagingPane() { + setLayout(FRGUIPaneFactory.createBorderLayout()); + setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); + + tabbedPane = new UITabbedPane(); + add(tabbedPane, BorderLayout.CENTER); + + formThemesManagerPane = TemplateThemeGridControlPane.createFormThemesManagerPane(); + formThemesManagerPane.startListenThemeConfig(); + reportThemesManagerPane = TemplateThemeGridControlPane.createReportThemesManagerPane(); + reportThemesManagerPane.startListenThemeConfig(); + + tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Form_Tab"), formThemesManagerPane); + tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Report_Tab"), reportThemesManagerPane); + + tabbedPane.setSelectedIndex(0); + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + TemplateThemeConfig config = template.getUsingTemplateThemeConfig(); + if (config == reportThemesManagerPane.getConfig()) { + tabbedPane.setSelectedIndex(1); + } + } + + @Override + public TemplateThemeConfig getConfig() { + if (tabbedPane.getSelectedIndex() == 0) { + return FormThemeConfig.getInstance(); + } else { + return ReportThemeConfig.getInstance(); + } + } + + @Override + public void exit() { + formThemesManagerPane.stopListenThemeConfig(); + formThemesManagerPane.stopAsyncFetchTheme(); + reportThemesManagerPane.stopListenThemeConfig(); + reportThemesManagerPane.stopAsyncFetchTheme(); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title"); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPane.java similarity index 92% rename from designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java rename to designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPane.java index fca01386c..3b9cb7bdc 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPane.java @@ -2,7 +2,6 @@ package com.fr.design.mainframe.theme; import com.fr.base.theme.TemplateTheme; import com.fr.base.theme.TemplateThemeConfig; -import com.fr.base.theme.settings.ThemeThumbnail; import com.fr.design.designer.IntervalConstants; import com.fr.design.dialog.BasicPane; import com.fr.design.event.ChangeEvent; @@ -13,6 +12,7 @@ import com.fr.stable.StringUtils; import javax.swing.BorderFactory; import javax.swing.JPanel; +import javax.swing.ScrollPaneConstants; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; @@ -27,12 +27,12 @@ import java.util.Map; * @version 1.0 * Created by Starryi on 2021/8/13 */ -public class TemplateThemeListPane extends BasicPane { +public class TemplateThemeGridPane extends BasicPane { public static final int BLOCK_COUNT_ROW_LINE = 3; public static final int BLOCK_GAP = IntervalConstants.INTERVAL_L1; public static final int CONTENT_WIDTH = TemplateThemeBlock.CONTENT_WIDTH * BLOCK_COUNT_ROW_LINE + BLOCK_GAP * (BLOCK_COUNT_ROW_LINE - 1) + 10; public static final int BLOCK_ROWS_PER_PAGE = 3; - public static final int CONTENT_HEIGHT = TemplateThemeBlock.CONTENT_HEIGHT * BLOCK_ROWS_PER_PAGE + BLOCK_GAP * (BLOCK_ROWS_PER_PAGE + 1); + public static final int CONTENT_HEIGHT = Math.min(527, TemplateThemeBlock.CONTENT_HEIGHT * BLOCK_ROWS_PER_PAGE + BLOCK_GAP * (BLOCK_ROWS_PER_PAGE + 1)); public static final int ASYNC_FETCH_THEME_THREAD_COUNT = 10; private final AsyncThemeFetcher asyncThemeFetcher; @@ -51,7 +51,7 @@ public class TemplateThemeListPane extends BasicPane { private ChangeListener changeListener; - public TemplateThemeListPane(boolean displayTheme4NewTemplateMarker, TemplateThemeConfig config, TemplateThemeProfilePane profilePane) { + public TemplateThemeGridPane(boolean displayTheme4NewTemplateMarker, TemplateThemeConfig config, TemplateThemeProfilePane profilePane) { this.displayTheme4NewTemplateMarker = displayTheme4NewTemplateMarker; this.config = config; this.profilePane = profilePane; @@ -64,14 +64,14 @@ public class TemplateThemeListPane extends BasicPane { setLayout(FRGUIPaneFactory.createBorderLayout()); setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); - contentListPane.setBorder(BorderFactory.createEmptyBorder(BLOCK_GAP, 0, BLOCK_GAP, 0)); + contentListPane.setBorder(BorderFactory.createEmptyBorder(BLOCK_GAP, 0, BLOCK_GAP, 10)); contentListPane.setLayout(new GridLayout(0, BLOCK_COUNT_ROW_LINE, BLOCK_GAP, BLOCK_GAP)); fillContentListPane(); - JPanel wrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); - wrapper.add(contentListPane, BorderLayout.NORTH); - - UIScrollPane scrollPane = new UIScrollPane(wrapper); + UIScrollPane scrollPane = new UIScrollPane(contentListPane); + scrollPane.setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); + scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); scrollPane.setBorder(BorderFactory.createEmptyBorder()); add(scrollPane, BorderLayout.CENTER); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java index 19885763c..c302cf1ad 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java @@ -48,9 +48,6 @@ public abstract class TemplateThemePreviewPane extends int height = getHeight(); try { - // 使用TYPE_INT_RGB和new Color(255, 255, 255, 1)设置有透明背景buffer image, - // 使得创建出来的透明像素是(255, 255, 255, 1),而不是(0, 0, 0, 0) - // 这样不支持透明通道缩略图的旧设计器打开新设计器创建的模版时,就不会创建出拥有黑色背景的缩略图 image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = image.createGraphics(); // 创建一个支持透明背景的buffer image @@ -58,8 +55,6 @@ public abstract class TemplateThemePreviewPane extends g2d.dispose(); g2d = image.createGraphics(); - g2d.fillRect(0, 0, width, height); - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.clipRect(0, 0, width, height); @@ -80,6 +75,9 @@ public abstract class TemplateThemePreviewPane extends @Override public void paintComponent(Graphics g) { g.clearRect(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT); + // 添加个默认白色,否则因为上面的clearRect导致无背景时会出现黑色 + g.setColor(Color.WHITE); + g.fillRect(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT); paintBackground((Graphics2D) g); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java index caa495aac..f3187acaa 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java @@ -1,58 +1,39 @@ package com.fr.design.mainframe.theme; -import com.fr.base.theme.FineColorFlushUtils; -import com.fr.base.theme.FineColorManager; import com.fr.base.theme.TemplateTheme; import com.fr.base.theme.TemplateThemeConfig; import com.fr.base.theme.settings.ThemeThumbnail; -import com.fr.base.theme.settings.ThemedCellStyleList; -import com.fr.base.theme.settings.ThemedColorScheme; -import com.fr.design.designer.IntervalConstants; +import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.FineJOptionPane; -import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; import com.fr.design.gui.frpane.AttributeChangeListener; -import com.fr.design.gui.frpane.UITabbedPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.itextfield.UITextField; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.layout.TableLayout; -import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.theme.dialog.TemplateThemeProfileDialog; -import com.fr.design.mainframe.theme.edit.CellStyleListEditPane; -import com.fr.design.mainframe.theme.edit.ChartStyleEditPane; -import com.fr.design.mainframe.theme.edit.ui.ColorListExtendedPane; -import com.fr.design.mainframe.theme.edit.ui.ColorListPane; import com.fr.design.mainframe.theme.edit.ui.LabelUtils; +import com.fr.design.mainframe.theme.ui.AutoCheckTextField; +import com.fr.design.mainframe.theme.ui.AutoCheckThemeNameTextField; import com.fr.design.mainframe.theme.ui.BorderUtils; +import com.fr.design.mainframe.toast.DesignerToastMsgUtil; import com.fr.design.utils.gui.GUICoreUtils; -import com.fr.general.Inter; import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; import com.fr.transaction.CallBackAdaptor; + import javax.swing.BorderFactory; -import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Component; import java.awt.Dimension; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.FocusAdapter; -import java.awt.event.FocusEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.util.List; import static com.fr.design.i18n.Toolkit.i18nText; @@ -61,71 +42,35 @@ import static com.fr.design.i18n.Toolkit.i18nText; * @version 1.0 * Created by Starryi on 2021/8/13 */ -public abstract class TemplateThemeProfilePane extends AbstractAttrNoScrollPane { +public abstract class TemplateThemeProfilePane extends BasicPane { public static final int TITLE_BORDER_FONT = 12; public static final int LEFT_TITLE_PANE_WIDTH = 627; public static final int LEFT_TITLE_PANE_HEIGHT = 539; public static final int PREVIEW_PANE_WIDTH = LEFT_TITLE_PANE_WIDTH - 10; public static final int PREVIEW_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT - TITLE_BORDER_FONT - 16; - public static final int RIGHT_PANE_WIDTH = 362; - public static final int RIGHT_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT; - public static final int COLOR_SCHEME_TITLE_PANE_WIDTH = 298; - public static final int COLOR_SCHEME_TITLE_PANE_HEIGHT = 174 + TITLE_BORDER_FONT / 2; - protected TemplateThemePreviewPane themePreviewPane; - - protected UITextField nameTextField; - private UILabel nameErrorLabel; - protected ColorListPane colorListPane; - private ColorListExtendedPane colorListExtendedPane; - protected CellStyleListEditPane cellStyleSettingPane; - protected ChartStyleEditPane chartStyleSettingPane; + protected TemplateThemeEditorPane themeEditorPane; protected boolean isPopulating = false; - protected UITabbedPane uiTabbedPane; + protected boolean isMutable = false; - private final TemplateThemeConfig config; + protected final TemplateThemeConfig config; private UIButton saveButton = new UIButton(); private UIButton saveAsButton = new UIButton(); - private boolean refreshingThemedColor = false; - - private boolean currentIsNewTheme; - private T theme; - public TemplateThemeProfilePane(TemplateThemeConfig config) { + super(); this.config = config; - theme = config.createNewTheme(); - } - @Override - protected JPanel createContentPane() { - JPanel container = new JPanel(new BorderLayout(5, 0)); - container.add(createLeftPane(), BorderLayout.CENTER); - container.add(createRightPane(), BorderLayout.EAST); - addAttributeChangeListener(new AttributeChangeListener() { - @Override - public void attributeChange() { - if (!isPopulating && !refreshingThemedColor) { - valueChangeAction(); - } - } - }); - return container; - } - - @Override - protected void initContentPane() { - super.initContentPane(); - if (leftContentPane != null) { - // 修正 AbstractAttrNoScrollPane 的默认行为 - leftContentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 6)); - } + initializePane(); } - public void valueChangeAction() { - themePreviewPane.refresh(updateBean()); + private void initializePane() { + setLayout(new BorderLayout(5, 0)); + setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 6)); + add(createLeftPane(), BorderLayout.CENTER); + add(createRightPane(), BorderLayout.EAST); } @Override @@ -149,220 +94,55 @@ public abstract class TemplateThemeProfilePane extends return titleContainer; } private JPanel createRightPane() { - JPanel container = new JPanel(new BorderLayout(0, 0)); - container.setPreferredSize(new Dimension(RIGHT_PANE_WIDTH, RIGHT_PANE_HEIGHT)); - JPanel nameEditPane = createNameEditPane(); - container.add(nameEditPane, BorderLayout.NORTH); - - JPanel settingPane = new JPanel(new BorderLayout(0, IntervalConstants.INTERVAL_L1)); - container.add(settingPane, BorderLayout.CENTER); - settingPane.add(createColorSchemeEditPane(), BorderLayout.NORTH); - settingPane.add(createCustomEditorsPane(), BorderLayout.CENTER); - - uiTabbedPane.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - valueChangeAction(); - } - }); - - return container; - } - - private JPanel createNameEditPane() { - nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED); - nameErrorLabel.setVisible(false); - - nameTextField = new UITextField(); - nameTextField.setEnabled(false); - nameTextField.setPreferredSize(new Dimension(165, 20)); - nameTextField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, false, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); - } - } - - @Override - public void removeUpdate(DocumentEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, false, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); - } - } - - @Override - public void changedUpdate(DocumentEvent e) { - - } - }); - nameTextField.addFocusListener(new FocusAdapter() { - @Override - public void focusGained(FocusEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, false, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); - } - } - + themeEditorPane = createThemeEditorPane(); + themeEditorPane.addAttributeChangeListener(new AttributeChangeListener() { @Override - public void focusLost(FocusEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, true, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); + public void attributeChange() { + if (isPopulating) { + return; } + themePreviewPane.refresh(updateBean()); + saveButton.setEnabled(themeEditorPane.checkNameValid() && isMutable); } }); - - double p = TableLayout.PREFERRED; - - JPanel container = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{ - new Component[] { LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Name")), nameTextField }, - new Component[] { null, nameErrorLabel }, - }, new double[] { 20, 20}, new double[] { p, 165}, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_W0); - - container.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); - return container; - } - private JPanel createColorSchemeEditPane() { - colorListPane = new ColorListPane(); - colorListExtendedPane = new ColorListExtendedPane(); - - JPanel extendedContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); - colorListExtendedPane.setBackground(null); - colorListExtendedPane.setOpaque(false); - extendedContainer.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - extendedContainer.setBackground(Color.WHITE); - extendedContainer.add(colorListExtendedPane); - - double p = TableLayout.PREFERRED; - double[] rowSize = new double[]{p, p, p}; - double[] columnSize = {p, p}; - - JPanel colorListContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - colorListContainerPane.add(colorListPane, BorderLayout.WEST); - - JPanel previewLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - previewLabelPane.add(LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Preview_Label")), BorderLayout.NORTH); - - UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Tip"), new Color(153, 153, 153)); - tipLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); - - JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ - {LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Label")), colorListContainerPane}, - {null, tipLabel}, - {previewLabelPane, extendedContainer}, - }, - rowSize, columnSize, 18, 7); - content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - - JPanel borderContainer = new JPanel(new BorderLayout()); - borderContainer.setPreferredSize(new Dimension(COLOR_SCHEME_TITLE_PANE_WIDTH, COLOR_SCHEME_TITLE_PANE_HEIGHT)); - borderContainer.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Title"))); - borderContainer.add(content); - - JPanel container = new JPanel(new BorderLayout()); - container.add(borderContainer, BorderLayout.WEST); - - colorListPane.addColorChangeListener(new ChangeListener() { + themeEditorPane.addThemeNameCheckListener(new AutoCheckTextField.CheckListener() { @Override - public void stateChanged(ChangeEvent e) { - if (refreshingThemedColor) { + public void onChecked(String error, boolean valid) { + if (isPopulating) { return; } - List colors = colorListPane.update(); - refreshingThemedColor = true; - onColorSchemeChanged(colors); - refreshingThemedColor = false; + saveButton.setEnabled(valid && isMutable); } }); - return container; + return themeEditorPane; } - protected JPanel createCustomEditorsPane() { - JPanel container = new JPanel(new BorderLayout()); - container.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Custom_Settings_Title"))); - uiTabbedPane = new UITabbedPane(); - uiTabbedPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 1)); - container.add(uiTabbedPane, BorderLayout.NORTH); + public abstract TemplateThemePreviewPane createThemePreviewPane(); + public abstract TemplateThemeEditorPane createThemeEditorPane(); - return container; - } - public void addCustomEditorPane(String title, JComponent component) { - component.setPreferredSize(new Dimension(317, 239)); - uiTabbedPane.addTab(title, component); - } - protected JPanel createCellStyleSettingPane() { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - cellStyleSettingPane = new CellStyleListEditPane(); - cellStyleSettingPane.registerAttrChangeListener(new AttributeChangeListener() { - @Override - public void attributeChange() { - valueChangeAction(); - } - }); - container.add(cellStyleSettingPane); - return container; - } - protected JPanel createChartStyleSettingPane() { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - chartStyleSettingPane = new ChartStyleEditPane(); - container.add(chartStyleSettingPane); - return container; - } + public void populateBean(T theme) { + isPopulating = true; - public abstract TemplateThemePreviewPane createThemePreviewPane(); + isMutable = theme.isMutable(); - public void onColorSchemeChanged(List colors) { - colorListExtendedPane.populate(colors); - FineColorManager.FineColorReplaceByColorScheme replaceByColorScheme = new FineColorManager.FineColorReplaceByColorScheme(colors); - T theme = updateBean(); - FineColorFlushUtils.replaceCacheObject(theme, replaceByColorScheme); - FineColorManager.traverse(theme, replaceByColorScheme); - populateBean4CustomEditors(theme); - //图表渐变色 - chartStyleSettingPane.populateGradientBar(colors); + themeEditorPane.populateBean(theme); themePreviewPane.refresh(theme); - this.repaint(); - } - - public void populateBean(T theme) { - this.theme = theme; - isPopulating = true; String name = theme.getName(); - currentIsNewTheme = config.cachedFetch(name) == null; - - nameTextField.setText(name); - nameTextField.setEnabled(StringUtils.isEmpty(name)); if (saveButton != null) { - saveButton.setEnabled(theme.isMutable() && !currentIsNewTheme); + saveButton.setEnabled(isMutable); } if (saveAsButton != null) { - saveAsButton.setEnabled(!currentIsNewTheme); + saveAsButton.setEnabled(StringUtils.isNotEmpty(name)); } - - colorListPane.populate(theme.getColorScheme().getColors()); - colorListExtendedPane.populate(colorListPane.update()); - - populateBean4CustomEditors(theme); - - themePreviewPane.refresh(theme); isPopulating = false; } - protected void populateBean4CustomEditors(T theme) { - cellStyleSettingPane.populateBean(theme.getCellStyleList()); - chartStyleSettingPane.populateBean(theme.getChartStyle()); - } - public T updateBean() { - if (theme == null) { - theme = config.createNewTheme(); - } - - theme.setName(this.nameTextField.getText()); + T theme = themeEditorPane.updateBean(); Image thumbnailImage = themePreviewPane.createThumbnailImage(); if (thumbnailImage != null) { @@ -371,24 +151,55 @@ public abstract class TemplateThemeProfilePane extends theme.setThumbnail(thumbnail); } - ThemedCellStyleList cellStyleConfig = this.cellStyleSettingPane.updateBean(); - theme.setCellStyleList(cellStyleConfig); - - ThemedColorScheme colorScheme = theme.getColorScheme(); - colorScheme.setColors(this.colorListPane.update()); - theme.setColorScheme(colorScheme); - - theme.setChartStyle(this.chartStyleSettingPane.updateBean()); - - updateBean(theme); return theme; } - public List getCurrentColorScheme() { - return colorListPane.update(); + public TemplateThemeEditorPane getThemeEditorPane() { + return themeEditorPane; + } + + public void save(CallBackAdaptor callBack) { + T theme; + try { + theme = (T) updateBean().clone(); + } catch (CloneNotSupportedException ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + return; + } + save(theme, callBack); } + public void save(String name, CallBackAdaptor callBack) { + T theme = null; + try { + theme = (T) updateBean().clone(); + } catch (CloneNotSupportedException ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + return; + } + theme.setName(name); + save(theme, callBack); + } + private void save(T theme, CallBackAdaptor callBack) { + theme.setRemovable(true); + theme.setMutable(true); + config.addTheme(theme, true, new CallBackAdaptor() { + @Override + public void afterCommit() { + super.afterCommit(); + themeEditorPane.setThemeNameEditable(false); + callBack.afterCommit(); + } - protected abstract void updateBean(T theme); + @Override + public void afterRollback() { + super.afterRollback(); + FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this), + i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), + i18nText("Fine-Design_Basic_Alert"), + JOptionPane.WARNING_MESSAGE); + } + }); + } public UIButton createSaveButton() { saveButton = new UIButton(); @@ -397,29 +208,15 @@ public abstract class TemplateThemeProfilePane extends saveButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - T theme = updateBean(); - boolean canBeSaved = checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, true, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); - if (canBeSaved && theme != null) { - theme.setName(nameTextField.getText()); - config.addTheme(theme, true, new CallBackAdaptor() { - @Override - public void afterCommit() { - super.afterCommit(); - currentIsNewTheme = false; - nameTextField.setEnabled(false); - saveAsButton.setEnabled(true); - } - - @Override - public void afterRollback() { - super.afterRollback(); - FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this), - i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), - i18nText("Fine-Design_Basic_Alert"), - JOptionPane.WARNING_MESSAGE); - } - }); - } + save(new CallBackAdaptor() { + @Override + public void afterCommit() { + super.afterCommit(); + saveButton.setEnabled(false); + saveAsButton.setEnabled(true); + DesignerToastMsgUtil.toastPrompt(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Save_Successfully")); + } + }); } }); return saveButton; @@ -440,7 +237,7 @@ public abstract class TemplateThemeProfilePane extends private class SaveAsDialog extends JDialog { private final TemplateThemeProfileDialog parent; - private UITextField nameTextField; + private AutoCheckThemeNameTextField nameTextField; private UILabel nameErrorLabel; private UIButton confirmButton; @@ -466,6 +263,18 @@ public abstract class TemplateThemeProfilePane extends } private void initializeComponents() { + nameTextField = new AutoCheckThemeNameTextField<>(); + nameTextField.setThemeConfig(config); + nameTextField.setPreferredSize(new Dimension(180, 20)); + nameTextField.setNameCheckListener(new AutoCheckTextField.CheckListener() { + @Override + public void onChecked(String error, boolean valid) { + nameErrorLabel.setVisible(StringUtils.isNotEmpty(error)); + nameErrorLabel.setText(error); + confirmButton.setEnabled(valid); + } + }); + nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED); nameErrorLabel.setBorder(BorderFactory.createEmptyBorder(10, 20, 0, 0)); @@ -474,47 +283,16 @@ public abstract class TemplateThemeProfilePane extends confirmButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - saveAsNew(nameTextField.getText()); - } - }); - - nameTextField = new UITextField(); - nameTextField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(true, false, true, true, nameTextField, nameErrorLabel, confirmButton); - } - } - - @Override - public void removeUpdate(DocumentEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(true, false, true, true, nameTextField, nameErrorLabel, confirmButton); - } - } - - @Override - public void changedUpdate(DocumentEvent e) { - - } - }); - nameTextField.addFocusListener(new FocusAdapter() { - @Override - public void focusGained(FocusEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(true, false, true, true, nameTextField, nameErrorLabel, confirmButton); - } - } - - @Override - public void focusLost(FocusEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(true, true, true, true, nameTextField, nameErrorLabel, confirmButton); - } + save(nameTextField.getText(), new CallBackAdaptor() { + @Override + public void afterCommit() { + super.afterCommit(); + exit(); + parent.exit(); + } + }); } }); - nameTextField.setPreferredSize(new Dimension(180, 20)); } private JPanel createActionsContainer() { @@ -548,82 +326,8 @@ public abstract class TemplateThemeProfilePane extends return container; } - private void saveAsNew(String name) { - T newThemeObject = null; - try { - newThemeObject = (T) updateBean().clone(); - } catch (CloneNotSupportedException ex) { - FineLoggerFactory.getLogger().error(ex.getMessage(), ex); - return; - } - boolean canBeSaved = checkThemeCanBeSavedAndUpdateUI(true, true, true, true, nameTextField, nameErrorLabel, confirmButton); - if (canBeSaved && newThemeObject != null) { - newThemeObject.setName(name); - newThemeObject.setRemovable(true); - newThemeObject.setMutable(true); - config.addTheme(newThemeObject, true, new CallBackAdaptor() { - @Override - public void afterCommit() { - super.afterCommit(); - exit(); - parent.exit(); - } - - @Override - public void afterRollback() { - super.afterRollback(); - FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this), - i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), - i18nText("Fine-Design_Basic_Alert"), - JOptionPane.WARNING_MESSAGE); - } - }); - } - } - public void exit() { this.dispose(); } } - - private boolean isThemeNameEmpty(String name) { - return StringUtils.isEmpty(name); - } - private boolean isThemeNameDuplicated(String name) { - return config.cachedFetch(name) != null; - } - private boolean checkThemeCanBeSavedAndUpdateUI( - boolean checkEmpty, - boolean displayEmptyTip, - boolean checkDuplicated, - boolean displayDuplicatedTip, - UITextField textField, - UILabel errorLabel, UIButton... actionButtons) { - String name = textField.getText(); - - boolean valid = true; - errorLabel.setText(StringUtils.EMPTY); - if (checkEmpty && isThemeNameEmpty(name)) { - valid = false; - if (displayEmptyTip) { - errorLabel.setText(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Empty_Name_Error_Tip")); - } - } else if (checkDuplicated && isThemeNameDuplicated(name)) { - valid = false; - if (displayDuplicatedTip) { - errorLabel.setText(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Duplicated_Name_Error_Tip")); - } - } - - errorLabel.setVisible(!valid); - if (actionButtons != null && actionButtons.length > 0) { - for (UIButton button : actionButtons) { - if (button != null) { - button.setEnabled(valid); - } - } - } - - return valid; - } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java index ed2e22d29..875cc6bae 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java @@ -26,6 +26,9 @@ public abstract class TemplateThemeDialog extends JDialog { public static final int DIALOG_BOTTOM_ACTION_BUTTON_GAP = 10; public static final int DIALOG_BOTTOM_ACTION_BUTTON_HEIGHT = 20; + private final JPanel contentContainer; + private final JPanel actionContainer; + public TemplateThemeDialog(Window parent, String title, int contentWidth, int contentHeight) { super(parent, ModalityType.APPLICATION_MODAL); @@ -44,25 +47,45 @@ public abstract class TemplateThemeDialog extends JDialog { } }); GUICoreUtils.centerWindow(this); + + contentContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); + actionContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); + contentContainer.add(actionContainer, BorderLayout.SOUTH); + setContentPane(contentContainer); } - protected final JPanel createDialogContentPane(JPanel contentPane, UIButton[] rightButtons) { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - container.add(contentPane, BorderLayout.CENTER); - container.add(createActionsContainer(rightButtons), BorderLayout.SOUTH); - return container; + protected void setupContentPane() { + contentContainer.add(createContentPane(), BorderLayout.CENTER, 0); } - protected final JPanel createDialogContentPane(JPanel contentPane, UIButton[] leftButtons, UIButton[] rightButtons) { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - container.add(contentPane, BorderLayout.CENTER); - container.add(createActionsContainer(leftButtons, rightButtons), BorderLayout.SOUTH); - return container; + protected JPanel createContentPane() { + return new JPanel(); } + protected UIButton[] createLeftButtons() { + return new UIButton[] {}; + } + protected UIButton[] createRightButtons() { + return new UIButton[] {}; + } - private JPanel createActionsContainer(UIButton... buttons) { - return this.createActionsContainer(FlowLayout.RIGHT, buttons); + public void setupActionButtons() { + JPanel leftPane = createActionsContainer(FlowLayout.LEFT, createLeftButtons()); + JPanel rightPane = createActionsContainer(FlowLayout.RIGHT, createRightButtons()); + + actionContainer.removeAll(); + actionContainer.add(leftPane, BorderLayout.WEST); + actionContainer.add(rightPane, BorderLayout.EAST); + + actionContainer.invalidate(); + actionContainer.repaint(); + } + + protected final JPanel createDialogContentPane(JPanel contentPane, UIButton[] rightButtons) { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.add(contentPane, BorderLayout.CENTER); + container.add(createRightActionsContainer(rightButtons), BorderLayout.SOUTH); + return container; } private JPanel createActionsContainer(int align, UIButton... buttons) { @@ -84,21 +107,12 @@ public abstract class TemplateThemeDialog extends JDialog { return container; } - protected int getPaddingVertical(){ - return (DIALOG_BOTTOM_ACTION_BAR_HEIGHT - DIALOG_BOTTOM_ACTION_BUTTON_HEIGHT) / 2; + private JPanel createRightActionsContainer(UIButton... buttons) { + return createActionsContainer(FlowLayout.RIGHT, buttons); } - - - private JPanel createActionsContainer(UIButton[] leftButtons, UIButton[] rightButtons) { - JPanel leftPane = createActionsContainer(FlowLayout.LEFT, leftButtons); - JPanel rightPane = createActionsContainer(FlowLayout.RIGHT, rightButtons); - - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - container.add(leftPane, BorderLayout.WEST); - container.add(rightPane, BorderLayout.EAST); - - return container; + private int getPaddingVertical(){ + return (DIALOG_BOTTOM_ACTION_BAR_HEIGHT - DIALOG_BOTTOM_ACTION_BUTTON_HEIGHT) / 2; } public void exit() { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeGridPagesDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeGridPagesDialog.java new file mode 100644 index 000000000..9711e8e8a --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeGridPagesDialog.java @@ -0,0 +1,58 @@ +package com.fr.design.mainframe.theme.dialog; + +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.theme.TemplateThemeGridPagesPane; +import com.fr.design.mainframe.theme.TemplateThemeGridPane; + +import javax.swing.JPanel; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/8/13 + */ +public class TemplateThemeGridPagesDialog extends TemplateThemeDialog implements TemplateThemeGridPagesPane.PageChangeListener { + public static final int CONTENT_WIDTH = TemplateThemeGridPane.CONTENT_WIDTH + 40; + public static final int CONTENT_HEIGHT = TemplateThemeGridPane.CONTENT_HEIGHT + 37; + + protected TemplateThemeGridPagesPane overallPane; + + public TemplateThemeGridPagesDialog() { + super(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT); + + setupContentPane(); + setupActionButtons(); + } + + @Override + protected JPanel createContentPane() { + overallPane = new TemplateThemeGridPagesPane(); + overallPane.setPageChangeListener(this); + return overallPane; + } + + @Override + protected UIButton[] createLeftButtons() { + return overallPane.createLeftButtons(); + } + + @Override + protected UIButton[] createRightButtons() { + return overallPane.createRightButtons(); + } + + @Override + public void exit() { + overallPane.exit(); + super.exit(); + } + + @Override + public void onPageChangeListener() { + setupActionButtons(); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java index 0049092a0..93e5b09e6 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java @@ -12,8 +12,9 @@ import com.fr.design.gui.frpane.UITabbedPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.JTemplate; -import com.fr.design.mainframe.theme.TemplateThemeManagePane; +import com.fr.design.mainframe.theme.TemplateThemeGridControlPane; import com.fr.design.mainframe.theme.provider.ThemeManageActionProvider; import javax.swing.BorderFactory; @@ -32,106 +33,10 @@ import java.util.Set; * @version 1.0 * Created by Starryi on 2021/8/13 */ -public class TemplateThemeManageDialog extends TemplateThemeDialog { +public class TemplateThemeManageDialog extends TemplateThemeGridPagesDialog { - private final TemplateThemeManageDialogContentPane contentPane; - - public TemplateThemeManageDialog(Window parent) { - super(parent, Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title"), - TemplateThemeManageDialogContentPane.CONTENT_WIDTH, TemplateThemeManageDialogContentPane.CONTENT_HEIGHT); - contentPane = new TemplateThemeManageDialogContentPane(); - - setContentPane(createDialogContentPane(contentPane, createActionButtons())); - } - - @Override - public void exit(){ - contentPane.exit(); - super.exit(); - } - - private UIButton[] createActionButtons() { - List uiButtonList = new ArrayList<>(); - - Set providers = ExtraDesignClassManager.getInstance().getArray(ThemeManageActionProvider.MARK_STRING); - for (ThemeManageActionProvider provider : providers) { - uiButtonList.add(provider.createButton(new ThemeManageActionProvider.ThemeManageActionContext() { - - @Override - public TemplateThemeDialog getDialog() { - return TemplateThemeManageDialog.this; - } - - @Override - public TemplateThemeConfig getConfig() { - return contentPane.getConfig(); - } - })); - } - - uiButtonList.add(createCompleteButton()); - - return uiButtonList.toArray(new UIButton[]{}); - } - - private UIButton createCompleteButton() { - UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Complete")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - exit(); - } - }); - return button; - } - - public static class TemplateThemeManageDialogContentPane extends JPanel { - public static final int CONTENT_WIDTH = TemplateThemeManagePane.CONTENT_WIDTH + 24; - public static final int CONTENT_HEIGHT = TemplateThemeManagePane.CONTENT_HEIGHT + 40; - - private final UITabbedPane tabbedPane; - private final TemplateThemeManagePane formThemesManagerPane; - private final TemplateThemeManagePane reportThemesManagerPane; - - public TemplateThemeManageDialogContentPane() { - setLayout(FRGUIPaneFactory.createBorderLayout()); - setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); - setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); - - tabbedPane = new UITabbedPane(); - add(tabbedPane, BorderLayout.NORTH); - - formThemesManagerPane = TemplateThemeManagePane.createFormThemesManagerPane(); - formThemesManagerPane.startListenThemeConfig(); - reportThemesManagerPane = TemplateThemeManagePane.createReportThemesManagerPane(); - reportThemesManagerPane.startListenThemeConfig(); - - tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Form_Tab"), formThemesManagerPane); - tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Report_Tab"), reportThemesManagerPane); - - tabbedPane.setSelectedIndex(0); - JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (template != null) { - TemplateThemeConfig config = template.getUsingTemplateThemeConfig(); - if (config == reportThemesManagerPane.getConfig()) { - tabbedPane.setSelectedIndex(1); - } - } - } - - public TemplateThemeConfig getConfig() { - if (tabbedPane.getSelectedIndex() == 0) { - return FormThemeConfig.getInstance(); - } else { - return ReportThemeConfig.getInstance(); - } - } - - public void exit() { - formThemesManagerPane.stopListenThemeConfig(); - formThemesManagerPane.stopAsyncFetchTheme(); - reportThemesManagerPane.stopListenThemeConfig(); - reportThemesManagerPane.stopAsyncFetchTheme(); - } + public TemplateThemeManageDialog() { + super(); + overallPane.showThemeManagingPane(); } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java index 3a6a9d383..a76597f8e 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java @@ -25,22 +25,33 @@ import java.util.Set; * Created by Starryi on 2021/8/13 */ public class TemplateThemeProfileDialog extends TemplateThemeDialog { - private static final int PADDING_VERTICAL = 4; public static TemplateThemeProfilePane currentVisibleProfilePane; public static final int CONTENT_WIDTH = 1010; public static final int CONTENT_HEIGHT = 542; + private final TemplateThemeProfilePane profilePane; public TemplateThemeProfileDialog(Window parent, TemplateThemeProfilePane profilePane) { super(parent, profilePane.getTitle(), CONTENT_WIDTH, CONTENT_HEIGHT); + this.profilePane = profilePane; + TemplateThemeProfileDialog.currentVisibleProfilePane = profilePane; + + setupContentPane(); + setupActionButtons(); + } + + @Override + protected JPanel createContentPane() { JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane(); content.setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); content.add(profilePane, BorderLayout.CENTER); + return content; + } - setContentPane(createDialogContentPane(content, createActionButtons(profilePane))); - - currentVisibleProfilePane = profilePane; + @Override + protected UIButton[] createRightButtons() { + return createActionButtons(profilePane); } @Override @@ -51,7 +62,7 @@ public class TemplateThemeProfileDialog extends Templat public static List getEditingColorScheme() { if (currentVisibleProfilePane != null) { - return currentVisibleProfilePane.getCurrentColorScheme(); + return currentVisibleProfilePane.getThemeEditorPane().getCurrentColorScheme(); } return null; } @@ -60,10 +71,6 @@ public class TemplateThemeProfileDialog extends Templat return currentVisibleProfilePane != null; } - protected int getPaddingVertical(){ - return PADDING_VERTICAL; - } - private UIButton[] createActionButtons(final TemplateThemeProfilePane profilePane) { List uiButtonList = new ArrayList<>(); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java index 9c9f9220e..420a7ed43 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java @@ -1,111 +1,13 @@ package com.fr.design.mainframe.theme.dialog; -import com.fr.base.theme.TemplateTheme; -import com.fr.base.theme.TemplateThemeConfig; -import com.fr.base.theme.ThemedTemplate; -import com.fr.design.event.ChangeEvent; -import com.fr.design.event.ChangeListener; -import com.fr.design.gui.ibutton.UIButton; -import com.fr.design.i18n.Toolkit; -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.mainframe.theme.TemplateThemeListPane; -import com.fr.design.mainframe.theme.ui.BorderUtils; -import com.fr.workspace.WorkContext; - -import javax.swing.BorderFactory; -import javax.swing.JPanel; -import javax.swing.border.CompoundBorder; -import java.awt.BorderLayout; -import java.awt.Window; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - /** * @author Starryi * @version 1.0 * Created by Starryi on 2021/8/13 */ -public class -TemplateThemeUsingDialog extends TemplateThemeDialog { - public static final int CONTENT_WIDTH = TemplateThemeListPane.CONTENT_WIDTH + 42; - public static final int CONTENT_HEIGHT = TemplateThemeListPane.CONTENT_HEIGHT + 23; - - private final TemplateThemeListPane themeListPane; - private final ThemedTemplate currentTemplate; - - public TemplateThemeUsingDialog(Window parent, ThemedTemplate template, TemplateThemeConfig config) { - super(parent, Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT); - - this.currentTemplate = template; - this.themeListPane = new TemplateThemeListPane<>(false, config, null); - - JPanel content = createContent(); - UIButton openThemeManagerButton = createOpenThemeManagerButton(); - UIButton completeButton = createCompleteButton(); - - setContentPane(createDialogContentPane(content, - new UIButton[]{ openThemeManagerButton }, - new UIButton[]{ completeButton } - )); - - themeListPane.startListenThemeConfig(); - - themeListPane.setSelectedChangeListener(new ChangeListener() { - @Override - public void fireChanged(ChangeEvent event) { - TemplateTheme theme = themeListPane.getSelectedTheme(); - if (theme != null) { - currentTemplate.setTemplateTheme(theme); - themeListPane.repaint(); - } - } - }); - } - - private JPanel createContent() { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - container.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); - - JPanel themeListPaneContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); - themeListPaneContainer.setBorder(new CompoundBorder( - BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Select"), 12), - BorderFactory.createEmptyBorder(0, 10, 0, 10) - )); - themeListPaneContainer.add(themeListPane, BorderLayout.CENTER); - container.add(themeListPaneContainer, BorderLayout.CENTER); - - return container; - } - - private UIButton createOpenThemeManagerButton() { - if (WorkContext.getCurrent().isRoot()) { - UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - TemplateThemeManageDialog dialog = new TemplateThemeManageDialog(TemplateThemeUsingDialog.this); - dialog.setVisible(true); - } - }); - return button; - } - return null; - } - - private UIButton createCompleteButton() { - UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Complete")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - exit(); - } - }); - return button; - } - - public void exit() { - themeListPane.stopListenThemeConfig(); - themeListPane.stopAsyncFetchTheme(); - super.exit(); +public class TemplateThemeUsingDialog extends TemplateThemeGridPagesDialog { + public TemplateThemeUsingDialog() { + super(); + overallPane.showThemeUsingPane(); } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java index 53e216b0d..de62a195d 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java @@ -2,8 +2,7 @@ package com.fr.design.mainframe.theme.edit; import com.fr.base.theme.settings.ThemedComponentStyle; import com.fr.design.designer.IntervalConstants; -import com.fr.design.dialog.AttrScrollPane; -import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.style.ComponentBodyStylePane; import com.fr.design.gui.style.ComponentIntegralStylePane; import com.fr.design.gui.style.ComponentTitleStylePane; @@ -18,10 +17,9 @@ import com.fr.general.act.BorderPacker; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JPanel; -import javax.swing.JScrollPane; +import javax.swing.JTextArea; import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Dimension; /** * @author Starryi @@ -50,7 +48,8 @@ public class ComponentStyleEditPane extends JPanel { }, new JComponent[] { createTabContainer(componentTitleStylePane), createTabContainer(componentBodyStylePane), createTabContainer(componentIntegralStylePane) } ); - add(content, BorderLayout.NORTH); + content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + add(content, BorderLayout.CENTER); } public void populateBean(ThemedComponentStyle style) { @@ -115,21 +114,20 @@ public class ComponentStyleEditPane extends JPanel { } private JComponent createTabContainer(final JPanel component) { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - container.setPreferredSize(new Dimension(container.getPreferredSize().width, 220)); + JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane(); JPanel tipLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); tipLabelPane.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); - UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Component_Style_Tip"), new Color(153, 153, 153)); + JTextArea tipLabel = LabelUtils.createAutoWrapLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Component_Style_Tip"), new Color(153, 153, 153)); tipLabelPane.add(tipLabel); - container.add(tipLabelPane, BorderLayout.NORTH); - - container.add(new AttrScrollPane() { - @Override - protected JPanel createContentPane() { - return component; - } - }, BorderLayout.CENTER); + content.add(tipLabelPane, BorderLayout.NORTH); + content.add(component, BorderLayout.CENTER); + + UIScrollPane scrollPane = new UIScrollPane(content); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.add(scrollPane, BorderLayout.CENTER); return container; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java index 53e4d9a91..b2d182422 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java @@ -12,7 +12,7 @@ import com.fr.design.gui.frpane.AttributeChangeListener; import com.fr.design.gui.style.AbstractBasicStylePane; import com.fr.design.gui.style.AlignmentPane; import com.fr.design.gui.style.BorderPane; -import com.fr.design.gui.style.FormatPane; +import com.fr.design.gui.style.TextFontTippedPane; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.theme.ui.BorderUtils; @@ -94,7 +94,7 @@ public class CellStyleEditPane extends MultiTabPane { @Override protected List initPaneList() { paneList = new ArrayList<>(); - paneList.add(new FormatPane()); + paneList.add(new TextFontTippedPane(false)); paneList.add(new BorderPane()); paneList.add(new AlignmentPane()); return paneList; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java index 7104572da..a70a24d8d 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java @@ -2,7 +2,7 @@ package com.fr.design.mainframe.theme.edit.cell; import com.fr.design.dialog.BasicPane; import com.fr.design.gui.style.AlignmentPane; -import com.fr.design.gui.style.FormatPane; +import com.fr.design.gui.style.TextFontTippedPane; import java.util.ArrayList; import java.util.List; @@ -12,7 +12,7 @@ public class NoBorderPaneCellStyleEditPane extends CellStyleEditPane { @Override protected List initPaneList() { paneList = new ArrayList<>(); - paneList.add(new FormatPane()); + paneList.add(new TextFontTippedPane(false)); paneList.add(new AlignmentPane()); return paneList; } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java index 2b099ed30..13769cfc6 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java @@ -3,6 +3,9 @@ package com.fr.design.mainframe.theme.edit.ui; import com.fr.design.gui.ilable.UILabel; import com.fr.general.FRFont; +import javax.swing.BorderFactory; +import javax.swing.JTextArea; +import javax.swing.plaf.basic.BasicTextAreaUI; import java.awt.Color; import java.awt.Font; @@ -26,4 +29,20 @@ public class LabelUtils { uiLabel.setFont(newFont); return uiLabel; } + + public static JTextArea createAutoWrapLabel(String title, Color color) { + JTextArea tipLabel = new JTextArea(); + tipLabel.setUI(new BasicTextAreaUI()); + tipLabel.setForeground(color); + Font newFont = FRFont.getInstance(tipLabel.getFont().getFontName(), Font.PLAIN, 12); + tipLabel.setFont(newFont); + tipLabel.setBorder(BorderFactory.createEmptyBorder()); + tipLabel.setEnabled(false); + tipLabel.setText(title); + tipLabel.setLineWrap(true); + tipLabel.setWrapStyleWord(true); + tipLabel.setOpaque(false); + tipLabel.setBackground(null); + return tipLabel; + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java index 3f4667e11..c1c837167 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java @@ -25,7 +25,6 @@ public class TabbedPane extends JPanel { public TabbedPane(String[] names, JComponent[] panes) { setLayout(FRGUIPaneFactory.createBorderLayout()); - setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); for (JComponent pane :panes) { pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java index cb854a3f3..20e418960 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java @@ -31,6 +31,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; +import java.awt.Insets; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; @@ -99,7 +100,20 @@ public abstract class ComponentPreviewPane extends UINoOpaquePanel implements Th Utils.clipByRoundBorder(g2d, getWidth(), getHeight(), roundedBorder.getRoundedCorner(), roundedBorder.getThickness()); } - int titleHeight = titlePane == null ? 0 : titlePane.getHeight(); + Border containerBorder = container.getBorder(); + Insets insets = containerBorder.getBorderInsets(container); + int titleHeight = titlePane == null ? 0 : titlePane.getHeight() + insets.top; + //绘制标题背景 + if (titlePane != null) { + Label data = titlePane.getData(); + float opacity = data.getBackgroundOpacity(); + Background background = data.getBackground(); + if (background != null) { + Utils.paintBackground((Graphics2D) g, background, new Rectangle2D.Double(0, 0, getWidth(), titleHeight), opacity); + } + } + + //绘制主体背景 Utils.paintBackground(g2d, style.getBackground(), new Rectangle2D.Double(0, titleHeight, getWidth(), getHeight() - titleHeight), style.getAlpha()); Utils.paintBackground(g2d, style.getBorderImage(), new Rectangle2D.Double(0, 0, getWidth(), getHeight()), style.getBorderImageOpacity()); @@ -133,17 +147,14 @@ public abstract class ComponentPreviewPane extends UINoOpaquePanel implements Th this.setBorder(new BottomLineBorder(componentStyle.getStyle().getColor(), componentStyle.getStyle().getBorder())); } + public Label getData(){ + return data; + } + @Override public void paintComponent(Graphics g) { super.paintComponent(g); - Dimension size = getSize(); - Background background = data.getBackground(); - float opacity = data.getBackgroundOpacity(); - if (background != null) { - Utils.paintBackground((Graphics2D) g, background, new Rectangle2D.Double(0, 0, size.getWidth(), size.getHeight()), opacity); - } - Graphics2D g2d = (Graphics2D) g.create(); Background inset = data.getInsetImage(); Image insetImage = inset instanceof ImageBackground ? ((ImageBackground) inset).getImage() : null; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java index 18ac4b962..25a1daee9 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java @@ -14,6 +14,7 @@ import com.fr.design.mainframe.theme.preview.ecpreview.ECComponentPreviewPane; import com.fr.general.Background; import com.fr.log.FineLoggerFactory; import com.fr.plugin.chart.PiePlot4VanChart; +import com.fr.plugin.chart.attr.VanChartLegend; import com.fr.plugin.chart.attr.axis.VanChartAxis; import com.fr.plugin.chart.base.AttrLabel; import com.fr.plugin.chart.base.VanChartTools; @@ -34,7 +35,6 @@ import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; import static com.fr.design.i18n.Toolkit.i18nText; - /** * @author Starryi * @version 1.0 @@ -65,7 +65,7 @@ public class FormThemePreviewPane extends TemplateThemePreviewPane { } }; columnChartPanel.setLayout(new BorderLayout()); - columnChartPreviewPane = createChartPreviewPane(initColumnChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Column_Title")); + columnChartPreviewPane = createChartPreviewPane(initColumnChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Comp_Title1")); columnChartPanel.add(columnChartPreviewPane, BorderLayout.CENTER); JPanel pieChartPanel = new UINoOpaquePanel() { @@ -74,7 +74,7 @@ public class FormThemePreviewPane extends TemplateThemePreviewPane { } }; pieChartPanel.setLayout(new BorderLayout()); - pieChartPreviewPane = createChartPreviewPane(initPieChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Pie_Title")); + pieChartPreviewPane = createChartPreviewPane(initPieChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Comp_Title2")); pieChartPanel.add(pieChartPreviewPane, BorderLayout.CENTER); chartContent.add(columnChartPanel, BorderLayout.CENTER); chartContent.add(pieChartPanel, BorderLayout.EAST); @@ -180,11 +180,14 @@ public class FormThemePreviewPane extends TemplateThemePreviewPane { vanChartTools.setFullScreen(false); PiePlot4VanChart plot = chart.getPlot(); - plot.getLegend().setPosition(Constants.BOTTOM); + VanChartLegend legend = (VanChartLegend) plot.getLegend(); + legend.setPosition(Constants.BOTTOM); + legend.setCustomSize(true); + legend.setMaxHeight(28); plot.getGradientStyle().setGradientType(GradientType.NONE); plot.setInnerRadiusPercent(75); plot.getRadius().setRadiusType(RadiusType.FIXED); - plot.getRadius().setRadius(80); + plot.getRadius().setRadius(70); Object[] category = {StringUtils.EMPTY}; Object[] series = {"A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1"}; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java index 4493ed263..5f7725ffa 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java @@ -2,20 +2,16 @@ package com.fr.design.mainframe.theme.preview.ecpreview; import com.fr.base.theme.TemplateTheme; import com.fr.base.theme.settings.ThemedCellStyleList; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.theme.preview.UINoOpaquePanel; import com.fr.design.mainframe.theme.preview.ecpreview.cell.AbstractPreviewCell; import com.fr.design.mainframe.theme.preview.ecpreview.cell.PreviewCell; -import com.fr.log.FineLoggerFactory; - import javax.swing.BorderFactory; import javax.swing.JPanel; - import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; -import java.io.BufferedReader; -import java.io.StringReader; import java.util.ArrayList; import java.util.List; @@ -25,70 +21,41 @@ import java.util.List; * Created by Starryi on 2021/8/13 */ public class ECPreviewPane extends AbstractECPreviewPane { - private static String csv = - "城市 当月目标 当月完成 月完成率 年完成率\n" + - "合肥市 248,938 348,938 140% 140%\n" + - "邵阳市 248,938 348,938 140% 140%\n" + - "合计 1,071,460 1,371,460 128% 128%"; - private final List DATA_LIST = createDataList(); - private static final String BLANK_CHAR = " "; - private List headerCellList = new ArrayList<>(); - private List contentCellList = new ArrayList<>(); - private List hightLightCellList = new ArrayList<>(); - - private List createDataList() { - List data = new ArrayList<>(); - try (BufferedReader reader = new BufferedReader(new StringReader(csv))) { - String textLine; - while ((textLine = reader.readLine()) != null) { - String[] texts = textLine.split(BLANK_CHAR); - data.add(texts); - } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - return data; - } - + private final List headerCellList = new ArrayList<>(); + private final List contentCellList = new ArrayList<>(); + private final List highLightCellList = new ArrayList<>(); + private static final int COL_COUNT = 5; + private static final int CONTENT_ROW_COUNT = 2; public ECPreviewPane() { this.setPreferredSize(new Dimension(517, 147)); this.setBorder(BorderFactory.createEmptyBorder(0, 1, 2, 1)); this.setLayout(FRGUIPaneFactory.createBorderLayout()); - String[] titleArr = DATA_LIST.get(0); - String[] endArr = DATA_LIST.get(DATA_LIST.size() - 1); JPanel titlePane = new UINoOpaquePanel(new GridLayout()); this.add(titlePane, BorderLayout.NORTH); - for (String title : titleArr) { - PreviewCell cell = new PreviewCell(title); + for (int i = 0; i < COL_COUNT; i++) { + PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header")); cell.setPreferredSize(new Dimension(103, 36)); titlePane.add(cell); headerCellList.add(cell); } - JPanel contentPane = new UINoOpaquePanel(new GridLayout(2, 5, 0, 0)); this.add(contentPane, BorderLayout.CENTER); - for (int i = 1; i < DATA_LIST.size() - 1; i++) { - String[] textLine = DATA_LIST.get(i); - for (int j = 0; j < textLine.length; j++) { - String text = textLine[j]; - PreviewCell cell = new PreviewCell(text); - cell.setPreferredSize(new Dimension(103, 33)); - contentPane.add(cell); - contentCellList.add(cell); - } + for (int i = 0; i < COL_COUNT * CONTENT_ROW_COUNT; i++) { + PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Main_Text")); + cell.setPreferredSize(new Dimension(103, 33)); + contentPane.add(cell); + contentCellList.add(cell); } JPanel endPane = new UINoOpaquePanel(new GridLayout()); this.add(endPane, BorderLayout.SOUTH); - for (String text : endArr) { - PreviewCell cell = new PreviewCell(text); + for (int i = 0; i < COL_COUNT; i++) { + PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Highlight_Text")); cell.setPreferredSize(new Dimension(103, 33)); endPane.add(cell); - hightLightCellList.add(cell); + highLightCellList.add(cell); } - - } @Override @@ -96,7 +63,7 @@ public class ECPreviewPane extends AbstractECPreviewPane { ThemedCellStyleList cellStyleConfig = theme.getCellStyleList(); refresh(headerCellList, getReportHeaderStyle(cellStyleConfig)); refresh(contentCellList, getMainContentStyle(cellStyleConfig)); - refresh(hightLightCellList, getHighLightStyle(cellStyleConfig)); + refresh(highLightCellList, getHighLightStyle(cellStyleConfig)); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java index 231233196..a933f3948 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java @@ -22,13 +22,15 @@ import java.util.ArrayList; import java.util.List; public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreviewed { - private List headerTitleCellList = new ArrayList<>(); - private List headerCellList = new ArrayList<>(); - private List titleCellList = new ArrayList<>(); - private List contentCellList = new ArrayList<>(); - private List highLightCellList = new ArrayList<>(); + private final List headerTitleCellList = new ArrayList<>(); + private final List headerCellList = new ArrayList<>(); + private final List titleCellList = new ArrayList<>(); + private final List contentCellList = new ArrayList<>(); + private final List highLightCellList = new ArrayList<>(); + private static final int CONTENT_ROW_COUNT = 3; + private static final int COL_COUNT = 5; - private PreviewPane previewPane; + private final PreviewPane previewPane; public ECReportPreviewPane() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); @@ -58,26 +60,26 @@ public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreview private JPanel createNorthPane() { JPanel northPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane(); - AbstractPreviewCell bigTitleCell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Big_Title")); + AbstractPreviewCell bigTitleCell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Cell_Style_Big_Title")); bigTitleCell.setPreferredSize(new Dimension(615, 46)); headerTitleCellList.add(bigTitleCell); northPane.add(bigTitleCell, BorderLayout.NORTH); - CornerPreviewCell cornerCell = new CornerPreviewCell(new String[]{Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Product"), - Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Data"), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Statistical_Dimension")}, - new Point2D[]{new Point(159, 71), new Point(226, 49)}); - cornerCell.setPreferredSize(new Dimension(226, 71)); + CornerPreviewCell cornerCell = new CornerPreviewCell(new String[]{Toolkit.i18nText("Fine-Design_Basic_Column_Name"), + Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Data"), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Row_Name")}, + new Point2D[]{new Point(159, 71), new Point(225, 49)}); + cornerCell.setPreferredSize(new Dimension(225, 71)); headerCellList.add(cornerCell); northPane.add(cornerCell, BorderLayout.WEST); JPanel centerPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane(); northPane.add(centerPane, BorderLayout.CENTER); - PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Statistical_By_Area")); + PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Small_Title")); titleCellList.add(cell); cell.setPreferredSize(new Dimension(308, 38)); centerPane.add(cell, BorderLayout.NORTH); JPanel eastSouthPane = new UINoOpaquePanel(new GridLayout()); - PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_East_China")); - PreviewCell cell2 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_South_China")); - PreviewCell cell3 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Subtotal")); + PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header")); + PreviewCell cell2 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header")); + PreviewCell cell3 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header")); headerCellList.add(cell1); headerCellList.add(cell2); headerCellList.add(cell3); @@ -92,14 +94,14 @@ public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreview JPanel centerPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane(); JPanel westPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane(); centerPane.add(westPane, BorderLayout.WEST); - PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Drink")); + PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Small_Title")); titleCellList.add(cell1); cell1.setPreferredSize(new Dimension(112, 153)); westPane.add(cell1, BorderLayout.WEST); JPanel gridPane = new UINoOpaquePanel(new GridLayout(5, 1)); - for (int i = 0; i < 5; i++) { - PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Apple_Juice")); - cell.setPreferredSize(new Dimension(114, 31)); + for (int i = 0; i < COL_COUNT; i++) { + PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header")); + cell.setPreferredSize(new Dimension(113, 31)); headerCellList.add(cell); gridPane.add(cell); } @@ -107,14 +109,16 @@ public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreview JPanel innerCenterPane = new UINoOpaquePanel(new GridLayout(5, 3)); centerPane.add(innerCenterPane, BorderLayout.CENTER); - for (int i = 0; i < 15; i++) { - PreviewCell cell = new PreviewCell("35600"); - cell.setPreferredSize(new Dimension(123, 31)); - if ((i + 1) % 3 == 0) { + for (int i = 0; i < COL_COUNT * CONTENT_ROW_COUNT; i++) { + PreviewCell cell ; + if ((i + 1) % CONTENT_ROW_COUNT == 0) { + cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Highlight_Text")); highLightCellList.add(cell); } else { + cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Main_Text")); contentCellList.add(cell); } + cell.setPreferredSize(new Dimension(123, 31)); innerCenterPane.add(cell); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckTextField.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckTextField.java new file mode 100644 index 000000000..9ce5a3d5d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckTextField.java @@ -0,0 +1,100 @@ +package com.fr.design.mainframe.theme.ui; + +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.stable.StringUtils; + +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/18 + */ +public class AutoCheckTextField extends UITextField implements DocumentListener, FocusListener { + private DuplicateChecker duplicatedChecker; + private CheckListener checkListener; + + public AutoCheckTextField() { + getDocument().addDocumentListener(this); + addFocusListener(this); + } + + public void setDuplicatedChecker(DuplicateChecker checker) { + this.duplicatedChecker = checker; + } + public void setNameCheckListener(CheckListener checkListener) { + this.checkListener = checkListener; + } + + private boolean isEmpty(String name) { + return StringUtils.isEmpty(name); + } + private boolean isDuplicated(String name) { + if (duplicatedChecker != null) { + return duplicatedChecker.isDuplicated(name); + } + return false; + } + private boolean checkValid(boolean notifyEmptyTip) { + String name = getText(); + + String error = StringUtils.EMPTY; + boolean valid = true; + if (isEditable()) { + if (isEmpty(name)) { + valid = false; + if (notifyEmptyTip) { + error = Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Empty_Name_Error_Tip"); + } + } else if (isDuplicated(name)) { + valid = false; + error = Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Duplicated_Name_Error_Tip"); + } + } + + if (checkListener != null) { + checkListener.onChecked(error, valid); + } + + return valid; + } + public boolean checkValid() { + return checkValid(true); + } + + @Override + public void insertUpdate(DocumentEvent e) { + checkValid(false); + } + + @Override + public void removeUpdate(DocumentEvent e) { + checkValid(false); + } + + @Override + public void changedUpdate(DocumentEvent e) { + + } + + @Override + public void focusGained(FocusEvent e) { + checkValid(false); + } + + @Override + public void focusLost(FocusEvent e) { + checkValid(true); + } + + public interface CheckListener { + void onChecked(String error, boolean valid); + } + public interface DuplicateChecker { + boolean isDuplicated(String name); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckThemeNameTextField.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckThemeNameTextField.java new file mode 100644 index 000000000..804c8493d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckThemeNameTextField.java @@ -0,0 +1,26 @@ +package com.fr.design.mainframe.theme.ui; + +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/18 + */ +public class AutoCheckThemeNameTextField extends AutoCheckTextField { + private TemplateThemeConfig config; + + public AutoCheckThemeNameTextField() { + setDuplicatedChecker(new DuplicateChecker() { + @Override + public boolean isDuplicated(String name) { + return config != null && config.contains(name); + } + }); + } + + public void setThemeConfig(TemplateThemeConfig config) { + this.config = config; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BreadcrumbBar.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BreadcrumbBar.java new file mode 100644 index 000000000..bc466972e --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BreadcrumbBar.java @@ -0,0 +1,114 @@ +package com.fr.design.mainframe.theme.ui; + +import com.fr.design.gui.ilable.UILabel; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.plaf.basic.BasicButtonUI; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/10/9 + */ +public class BreadcrumbBar extends JPanel { + private JButton currentCrumb; + + public BreadcrumbBar() { + setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); + } + + public void addCrumb(final String text, final BreadcrumbBackListener backListener) { + if (currentCrumb != null) { + currentCrumb.setSelected(false); + add(createSeparator()); + } + final JButton breadcrumb = createBreadcrumb(text); + breadcrumb.setSelected(true); + add(breadcrumb); + currentCrumb = breadcrumb; + + final int index = getComponentCount() - 1; + breadcrumb.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + removeTailCrumbs(index + 1); + + breadcrumb.setSelected(true); + currentCrumb = breadcrumb; + if (backListener != null) { + backListener.onBreadcrumbBack(text); + } + } + }); + } + + private void removeTailCrumbs(int from) { + Component[] components = getComponents(); + for (int i = from; i < components.length; i++) { + remove(components[i]); + } + revalidate(); + repaint(); + } + + public void clear() { + removeAll(); + currentCrumb = null; + } + + protected Component createSeparator() { + UILabel separator = new UILabel("/"); + separator.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8)); + separator.setPreferredSize(new Dimension(separator.getPreferredSize().width, 17)); + + return separator; + } + + protected JButton createBreadcrumb(String text) { + JButton button = new BreadcrumbButton(text); + button.setPreferredSize(new Dimension(button.getPreferredSize().width, 17)); + return button; + } + + public static class BreadcrumbButton extends JButton { + + public BreadcrumbButton(String text) { + super(text); + setMargin(new Insets(0, 0, 0, 0)); + setBorder(BorderFactory.createEmptyBorder()); + setUI(new BasicButtonUI()); + setBorderPainted(false); + setOpaque(false); + setBackground(null); + } + + @Override + public Insets getMargin() { + Insets insets = super.getMargin(); + if (insets != null) { + insets.set(0, 0, 0, 0); + } + return insets; + } + + @Override + public void setSelected(boolean b) { + super.setSelected(b); + setForeground(b ? new Color(0x419BF9) : new Color(0x838384)); + repaint(); + } + } + + public interface BreadcrumbBackListener { + void onBreadcrumbBack(String text); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java index 866c2fabe..c4ad83ca7 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java @@ -408,7 +408,9 @@ public abstract class ToolBarMenuDock { menuDef.addShortCut(new OpenRecentReportMenuDef()); - addCloseCurrentTemplateAction(menuDef); + if (!DesignModeContext.isDuchampMode()) { + addCloseCurrentTemplateAction(menuDef); + } scs = plus.shortcut4FileMenu(); if (!ArrayUtils.isEmpty(scs)) { @@ -467,6 +469,10 @@ public abstract class ToolBarMenuDock { return new UILabel(); } + public Component createGuideEntryPane() { + return new UILabel(); + } + public Component createNotificationCenterPane(){ return new UILabel(); } diff --git a/designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java b/designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java index 057b561fa..115b9617c 100644 --- a/designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java +++ b/designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java @@ -1,18 +1,8 @@ package com.fr.design.os.impl; -import com.fr.design.data.datapane.connect.ConnectionManagerPane; -import com.fr.design.dialog.BasicDialog; -import com.fr.design.dialog.DialogActionAdapter; -import com.fr.design.editlock.EditLockUtils; +import com.fr.design.data.datapane.connect.ConnectionListPane; import com.fr.design.mainframe.DesignerContext; -import com.fr.design.mainframe.DesignerFrame; -import com.fr.file.ConnectionConfig; import com.fr.stable.os.support.OSBasedAction; -import com.fr.transaction.CallBackAdaptor; -import com.fr.transaction.Configurations; -import com.fr.transaction.WorkerFacade; -import com.fr.report.LockItem; -import static com.fr.design.actions.server.ConnectionListAction.doWithDatasourceManager; /** * 数据连接窗口 @@ -33,54 +23,7 @@ public class DatabaseDialogAction implements OSBasedAction { } private void openDesignDatabaseManager() { - DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); - final ConnectionConfig datasourceManager = ConnectionConfig.getInstance(); - final ConnectionManagerPane databaseManagerPane = new ConnectionManagerPane() { - public void complete() { - ConnectionConfig connectionConfig = datasourceManager.mirror(); - populate(connectionConfig); - } - - protected void renameConnection(String oldName, String newName) { - datasourceManager.renameConnection(oldName, newName); - } - }; - final BasicDialog databaseListDialog = databaseManagerPane.showLargeWindow(designerFrame, null); - databaseListDialog.addDialogActionListener(new DialogActionAdapter() { - public void doOk() { - if (!databaseManagerPane.isNamePermitted()) { - databaseListDialog.setDoOKSucceed(false); - return; - } - Configurations.modify(new WorkerFacade(ConnectionConfig.class) { - @Override - public void run() { - databaseManagerPane.update(datasourceManager); - } - }.addCallBack(new CallBackAdaptor() { - @Override - public boolean beforeCommit() { - //如果更新失败,则不关闭对话框,也不写xml文件,并且将对话框定位在请重命名的那个对象页面 - return doWithDatasourceManager(datasourceManager, databaseManagerPane, databaseListDialog); - } - - @Override - public void afterCommit() { - DesignerContext.getDesignerBean("databasename").refreshBeanElement(); - // 定义数据连接弹窗关闭后,解锁 - EditLockUtils.unlock(LockItem.CONNECTION); - } - })); - } - - @Override - public void doCancel() { - super.doCancel(); - // 定义数据连接弹窗关闭后,解锁 - EditLockUtils.unlock(LockItem.CONNECTION); - } - }); - databaseListDialog.setVisible(true); + ConnectionListPane.showDialog(DesignerContext.getDesignerFrame()); } diff --git a/designer-base/src/main/java/com/fr/design/report/fit/menupane/ReportFitAttrAction.java b/designer-base/src/main/java/com/fr/design/report/fit/menupane/ReportFitAttrAction.java index 99943f7a5..36328d9bd 100644 --- a/designer-base/src/main/java/com/fr/design/report/fit/menupane/ReportFitAttrAction.java +++ b/designer-base/src/main/java/com/fr/design/report/fit/menupane/ReportFitAttrAction.java @@ -60,7 +60,7 @@ public class ReportFitAttrAction extends JTemplateAction { } final FitProvider wbTpl = (FitProvider) jwb.getTarget(); ReportFitAttr fitAttr = wbTpl.getReportFitAttr(); - TemplateFitAttrPane templateFitAttrPane = new TemplateFitAttrPane(); + TemplateFitAttrPane templateFitAttrPane = new TemplateFitAttrPane(jwb); showReportFitDialog(fitAttr, jwb, wbTpl, templateFitAttrPane); } diff --git a/designer-base/src/main/java/com/fr/design/report/fit/menupane/TemplateFitAttrPane.java b/designer-base/src/main/java/com/fr/design/report/fit/menupane/TemplateFitAttrPane.java index 393cbfc71..8854b0ee9 100644 --- a/designer-base/src/main/java/com/fr/design/report/fit/menupane/TemplateFitAttrPane.java +++ b/designer-base/src/main/java/com/fr/design/report/fit/menupane/TemplateFitAttrPane.java @@ -1,6 +1,5 @@ package com.fr.design.report.fit.menupane; -import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.JTemplate; import com.fr.design.report.fit.BaseFitAttrPane; @@ -15,7 +14,10 @@ import java.awt.event.ItemListener; public class TemplateFitAttrPane extends BaseFitAttrPane { - public TemplateFitAttrPane() { + private JTemplate jwb; + + public TemplateFitAttrPane(JTemplate jwb) { + this.jwb = jwb; initComponents(); } @@ -23,7 +25,7 @@ public class TemplateFitAttrPane extends BaseFitAttrPane { protected void initComponents() { super.initComponents(); for (FitAttrModel fitAttrModel : fitAttrModelList) { - if (fitAttrModel.isAvailable(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate())) { + if (fitAttrModel.isAvailable(jwb)) { populateModel(fitAttrModel); break; } @@ -71,7 +73,6 @@ public class TemplateFitAttrPane extends BaseFitAttrPane { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { if(isTemplateSingleSet()){ - JTemplate jwb = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); if (jwb != null) { FitProvider wbTpl = (FitProvider) jwb.getTarget(); ReportFitAttr fitAttr = wbTpl.getReportFitAttr(); diff --git a/designer-base/src/main/java/com/fr/design/style/color/NewColorSelectPane.java b/designer-base/src/main/java/com/fr/design/style/color/NewColorSelectPane.java index f38e69a8b..180055b3e 100644 --- a/designer-base/src/main/java/com/fr/design/style/color/NewColorSelectPane.java +++ b/designer-base/src/main/java/com/fr/design/style/color/NewColorSelectPane.java @@ -39,8 +39,10 @@ import java.util.List; public class NewColorSelectPane extends BasicPane implements ColorSelectable { private static final long serialVersionUID = -8634152305687249392L; - private static final int WIDTH = 197; - private static final int HEIGHT = 250; + private static final int WIDTH = 216; + private static final int HEIGHT = 230; + + private static final int DEFAULT_COLOR_HOR_INTERVAL = 4; //颜色衍生的数量 private static final int DEFAULT_DERIVE_COUNT = 5; @@ -81,7 +83,7 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable { initSelectButton(isSupportTransparent); // center JPanel centerPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane(); - centerPane.setBorder(BorderFactory.createEmptyBorder(10, 4, 0, 4)); + centerPane.setBorder(BorderFactory.createEmptyBorder(10, 6, 0, 6)); this.add(centerPane, BorderLayout.CENTER); menuColorPane = getMenuColorPane(); @@ -126,14 +128,14 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable { customButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); JPanel centerPane1 = new JPanel(new BorderLayout(0, 0)); - centerPane1.setBorder(BorderFactory.createEmptyBorder(9, 0, 11, 0)); + centerPane1.setBorder(BorderFactory.createEmptyBorder(8, 0, 9, 0)); centerPane1.add(customButton, BorderLayout.CENTER); customButton.setPreferredSize(new Dimension(197, 20)); centerPane.add(centerPane1); } private JPanel createStandardColorPane() { - JPanel jPanel = new JPanel(new GridLayout(1, 10, 3, 0)); + JPanel jPanel = new JPanel(new GridLayout(1, 10, DEFAULT_COLOR_HOR_INTERVAL, 0)); Color[] colorArray = ColorFactory.STANDARD_COLORS; for (int i = 0; i < colorArray.length; i++) { jPanel.add(new ColorCell(colorArray[i], this)); @@ -150,8 +152,8 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable { themeColorPane.add(menuColorPane, BorderLayout.SOUTH); menuColorPane.setLayout(new BorderLayout(0, 10)); - JPanel northPane = new JPanel(new GridLayout(1, 8, 3, 0)); - JPanel centerPane = new JPanel(new GridLayout(1, 8, 3, 0)); + JPanel northPane = new JPanel(new GridLayout(1, 8, DEFAULT_COLOR_HOR_INTERVAL, 0)); + JPanel centerPane = new JPanel(new GridLayout(1, 8, DEFAULT_COLOR_HOR_INTERVAL, 0)); menuColorPane.add(northPane, BorderLayout.NORTH); menuColorPane.add(centerPane, BorderLayout.CENTER); @@ -189,7 +191,7 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable { northPane.add(themeColorCellGrid[i][0]); } for (int i = 0; i < colorArray.length; i++) { - JPanel columnPane = new JPanel(new GridLayout(DEFAULT_DERIVE_COUNT - 1, 1, 0, 3)); + JPanel columnPane = new JPanel(new GridLayout(DEFAULT_DERIVE_COUNT - 1, 1, 0, 0)); for (int j = 1; j < DEFAULT_DERIVE_COUNT; j++) { columnPane.add(themeColorCellGrid[i][j]); } @@ -233,7 +235,7 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable { private void initMenuColorPane() { - menuColorPane.setLayout(new GridLayout(5, 8, 3, 3)); + menuColorPane.setLayout(new GridLayout(5, 8, DEFAULT_COLOR_HOR_INTERVAL, 0)); Color[] colorArray = this.getColorArray(); for (int i = 0; i < colorArray.length; i++) { Color color = colorArray[i] == null ? UsedColorPane.DEFAULT_COLOR : colorArray[i]; @@ -409,7 +411,7 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable { private void initialComponents() { int total = columns; JPanel panel = new JPanel(); - panel.setLayout(new GridLayout(1, columns + 1, 3, 3)); + panel.setLayout(new GridLayout(1, columns + 1, DEFAULT_COLOR_HOR_INTERVAL, 0)); panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); //最近使用颜色 Color[] colors = DesignerEnvManager.getEnvManager().getColorConfigManager().getColors(); diff --git a/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java b/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java index 90d6accf6..09fa2bbc0 100644 --- a/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java +++ b/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java @@ -26,6 +26,7 @@ import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.io.File; import java.util.Map; /** @@ -170,6 +171,10 @@ public class ModernUIPane extends BasicPane { public void clearCache() { if (browser != null) { browser.getCacheStorage().clearCache(); + File file = new File(browser.getContext().getCacheDir()); + if (file.exists()) { + file.delete(); + } } } diff --git a/designer-base/src/main/java/com/fr/design/utils/ComponentUtils.java b/designer-base/src/main/java/com/fr/design/utils/ComponentUtils.java index 1d9361138..24134dce1 100644 --- a/designer-base/src/main/java/com/fr/design/utils/ComponentUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/ComponentUtils.java @@ -1,11 +1,13 @@ package com.fr.design.utils; import com.fr.general.ComparatorUtils; +import com.fr.stable.StringUtils; import javax.swing.*; import java.awt.*; import java.awt.geom.Rectangle2D; import java.util.ArrayList; +import java.util.List; /** * 工具类,提供常用的工具方法 @@ -151,4 +153,62 @@ public class ComponentUtils { } return false; } + + public static Component findComponentByName(Component container, String componentName) { + Component target = null; + if (container instanceof Container) { + for (Component component: ((Container)container).getComponents()) { + if (componentName.equals(component.getName())) { + return component; + } + if (component instanceof JRootPane) { + JRootPane nestedJRootPane = (JRootPane)component; + target = findComponentByName(nestedJRootPane.getContentPane(), componentName); + } else if (component instanceof Container){ + target = findComponentByName( component, componentName); + } + if (target != null) { + return target; + } + } + } + return null; + } + + public static Component findComponentByClass(Component container, Class clazz) { + Component target = null; + if (container instanceof Container) { + for (Component component: ((Container)container).getComponents()) { + if (clazz.isInstance(component)) { + return component; + } + if (component instanceof JRootPane) { + JRootPane nestedJRootPane = (JRootPane)component; + target = findComponentByClass(nestedJRootPane.getContentPane(), clazz); + } else if (component instanceof Container){ + target = findComponentByClass(component, clazz); + } + if (target != null) { + return target; + } + } + } + return null; + } + + public static List findComponentsByClass(Component container, Class clazz) { + List components= new ArrayList<>(); + if (container instanceof Container) { + for (Component component: ((Container)container).getComponents()) { + if (clazz.isInstance(component)) { + components.add(component); + continue; + } + if (component instanceof Container){ + components.addAll(findComponentsByClass(component, clazz)); + } + } + } + return components; + } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java b/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java index 819660a99..3535078ab 100644 --- a/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java +++ b/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java @@ -7,12 +7,14 @@ import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrameFileDealerPane; import com.fr.design.mainframe.JTemplate; +import com.fr.design.utils.DesignUtils; import com.fr.design.worker.WorkerManager; import com.fr.exception.DecryptTemplateException; import com.fr.file.FILE; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; import javax.swing.JOptionPane; import javax.swing.SwingWorker; import javax.swing.UIManager; @@ -61,7 +63,7 @@ public class OpenWorker extends SwingWorker { } catch (CancellationException ignored) { return; } catch (Throwable t) { - processFailed(); + processFailed(StringUtils.EMPTY); Throwable cause = t.getCause(); if (cause instanceof DecryptTemplateException) { FineJOptionPane.showMessageDialog( @@ -91,6 +93,11 @@ public class OpenWorker extends SwingWorker { if (slowly && templateCallable != null) { try { JTemplate book = templateCallable.call(); + if (inValidDesigner(book)) { + String text = Toolkit.i18nText("Fine-Design_Report_Template_Version_Not_Match", DesignUtils.parseVersion(book.getTarget().getDesignerVersion())); + processFailed(text); + return; + } FILE tplFile = book.getEditingFILE(); JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); // 当前tab页是正在打开的模板 @@ -117,11 +124,21 @@ public class OpenWorker extends SwingWorker { WorkerManager.getInstance().removeWorker(taskName); } - private void processFailed() { + private boolean inValidDesigner(JTemplate jt) { + return jt.isOldDesigner(false) || (!jt.isJWorkBook() && jt.isNewDesigner(false)); + } + + private void processFailed(String text) { this.template.setOpenFailed(true); this.template.setOpening(false); - DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showOpenFailedCover(); - DesignerFrameFileDealerPane.getInstance().stateChange(); + JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + // 需要判断当前打开的模板是不是异步执行后失败的模板 是的话立即展示失败后的提示内容 否则只设置下失败的提示内容 + if (ComparatorUtils.equals(currentTemplate.getEditingFILE().getName(), this.template.getName())) { + DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showOpenFailedCover(text); + DesignerFrameFileDealerPane.getInstance().stateChange(); + } else { + this.template.setTemplateOpenFailedTip(text); + } WorkerManager.getInstance().removeWorker(taskName); } diff --git a/designer-base/src/main/java/com/fr/design/write/submit/CustomJobPane.java b/designer-base/src/main/java/com/fr/design/write/submit/CustomJobPane.java index d07d42b3e..6e4f2d803 100644 --- a/designer-base/src/main/java/com/fr/design/write/submit/CustomJobPane.java +++ b/designer-base/src/main/java/com/fr/design/write/submit/CustomJobPane.java @@ -13,6 +13,7 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.DialogActionAdapter; +import com.fr.stable.ListMap; import com.fr.stable.StringUtils; import com.fr.design.utils.gui.GUICoreUtils; @@ -115,7 +116,12 @@ public abstract class CustomJobPane extends BasicBeanPane { @Override public void populateBean(Object ob) { - if (ob instanceof AbstractClassJob) { + if (ob == null) { + // 自定义提交新增时初始化页面 REPORT-59256 + this.classNameTextField.setText(StringUtils.EMPTY); + this.objectProperiesPane.populateBean(new ListMap()); + } + else if (ob instanceof AbstractClassJob) { AbstractClassJob cj = (AbstractClassJob) ob; this.classNameTextField.setText(cj.getClassName()); this.objectProperiesPane.populateBean(cj.getPropertyMap()); diff --git a/designer-base/src/main/java/com/fr/env/ErrorDialog.java b/designer-base/src/main/java/com/fr/env/ErrorDialog.java index be91955f2..a26c673a4 100644 --- a/designer-base/src/main/java/com/fr/env/ErrorDialog.java +++ b/designer-base/src/main/java/com/fr/env/ErrorDialog.java @@ -39,7 +39,7 @@ public class ErrorDialog extends JDialog implements ActionListener { messagePanel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); MessageWithLink messageWithLink = new MessageWithLink(message + ",", Toolkit.i18nText("Fine-Design_Basic_Sync_Help"), CloudCenter.getInstance().acquireUrlByKind("help.replacejars", "https://help.fanruan.com/finereport/doc-view-3268.html")); - messageWithLink.setPreferredSize(new Dimension(108, 20)); + messageWithLink.setPreferredSize(new Dimension(150, 20)); JPanel messageLinkPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); messageLinkPane.setBorder(BorderFactory.createEmptyBorder(5, 8, 5, 0)); messageLinkPane.add(messageWithLink); diff --git a/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java b/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java index 8117f8739..fd4b98e33 100644 --- a/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java +++ b/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java @@ -5,6 +5,7 @@ import com.fr.design.dialog.link.MessageWithLink; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itextarea.UITextArea; +import com.fr.design.i18n.DesignSizeI18nManager; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; @@ -62,7 +63,7 @@ public class SyncFailedPluginsDialog extends JDialog { JPanel messagePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); MessageWithLink messageWithLink = new MessageWithLink(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Fail_Suggestion"),Toolkit.i18nText("Fine-Design_Basic_Sync_Deal_Immediately"), CloudCenter.getInstance().acquireUrlByKind("help.installplugins", "https://help.fanruan.com/finereport/doc-view-2198.html")); - messageWithLink.setPreferredSize(new Dimension(316, 20)); + messageWithLink.setPreferredSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.env.SyncFailedPluginsDialog.messageWithLink")); messagePane.add(messageWithLink); messagePane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 0)); diff --git a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java index 5ea393ba6..c21c82c75 100644 --- a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java +++ b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java @@ -29,6 +29,9 @@ import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.DesignerFrame; import com.fr.design.mainframe.JTemplate; import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.event.Event; +import com.fr.event.EventDispatcher; +import com.fr.event.Listener; import com.fr.file.filetree.FileNode; import com.fr.file.filter.ChooseFileFilter; import com.fr.file.filter.FILEFilter; @@ -45,6 +48,8 @@ import com.fr.stable.os.windows.WindowsDetector; import com.fr.stable.project.ProjectConstants; import com.fr.workspace.WorkContext; +import com.fr.workspace.Workspace; +import com.fr.workspace.WorkspaceEvent; import javax.swing.AbstractAction; import javax.swing.AbstractListModel; import javax.swing.ActionMap; @@ -66,7 +71,6 @@ import javax.swing.ListModel; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; -import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; @@ -644,7 +648,7 @@ public class FILEChooserPane extends BasicPane { this.suffix = suffix; if (!text.endsWith(suffix)) { - text = text + suffix; + text = removeSuffix(text) + suffix; } fileNameTextField.removeDocumentListener(); fileNameTextField.setText(text); @@ -660,6 +664,14 @@ public class FILEChooserPane extends BasicPane { fileNameTextField.setFilter(new DefaultCompletionFilter(names)); } + /** + * 移除文件后缀的方法 + * 解决cptx文件的另存为操作默认会出现双后缀的bug(xxx.cptx.cpt) + **/ + private String removeSuffix(String text){ + return FileExtension.CPTX.matchExtension(text) ? text.substring(0, text.length() - FileExtension.CPTX.getSuffix().length()) : text; + } + /** * 打开对话框 @@ -1326,6 +1338,12 @@ public class FILEChooserPane extends BasicPane { LocationButtonPane.this.repaint(10); } }); + EventDispatcher.listen(WorkspaceEvent.AfterSwitch, new Listener() { + @Override + public void on(Event event, Workspace param) { + setPopDir(null); + } + }); } public void highLightButton(FILE dir) { diff --git a/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TransformResultInfo.java b/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TransformResultInfo.java index e988e04e7..15e3c8bf9 100644 --- a/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TransformResultInfo.java +++ b/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TransformResultInfo.java @@ -57,7 +57,7 @@ public class TransformResultInfo { return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Success_Tip"); case UNSUPPORT: return transformLog + "\n" - + InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Unsupport_Tip"); + + InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_X_Unsupport_Tip"); } return transformLog; } diff --git a/designer-base/src/main/java/com/fr/nx/app/designer/utils/CptAndCptxCompatibilityUtil.java b/designer-base/src/main/java/com/fr/nx/app/designer/utils/CptAndCptxCompatibilityUtil.java new file mode 100644 index 000000000..0b1a65657 --- /dev/null +++ b/designer-base/src/main/java/com/fr/nx/app/designer/utils/CptAndCptxCompatibilityUtil.java @@ -0,0 +1,88 @@ +package com.fr.nx.app.designer.utils; + +import com.fr.base.extension.FileExtension; +import com.fr.design.mainframe.JTemplate; +import com.fr.file.FILE; +import com.fr.main.TemplateWorkBook; +import com.fr.report.report.Report; +import com.fr.report.stable.LayerReportAttr; +import com.fr.report.worksheet.WorkSheet; + +/** + * @author fly.li + * @version 10.0 + * Created on 2021/09/12 + */ +public class CptAndCptxCompatibilityUtil { + + /** + * 判断是否需要重新编译 + **/ + public static boolean needRecompile(String oldName, JTemplate jTemplate){ + FILE editingFILE = jTemplate.getEditingFILE(); + String path = editingFILE.getPath(); + //只有在旧文件是cptx文件并且新文件是cpt文件时才会改变报表引擎属性 + boolean isCptxConvertToCpt = FileExtension.CPTX.matchExtension(oldName) && FileExtension.CPT.matchExtension(path); + if (isCptxConvertToCpt && !setFrEngineAttr(jTemplate)){ + isCptxConvertToCpt = false; + } + return (isCptxConvertToCpt || isSaveAs(jTemplate, oldName, path)); + } + + /** + * 判断是不是cptx模板或者开启了的新引擎的cpt模板的另存为操作 + **/ + private static boolean isSaveAs(JTemplate jTemplate, String oldName, String newName){ + return isEngineXEnable(jTemplate.getTarget(), newName) && ((FileExtension.CPTX.matchExtension(oldName) && FileExtension.CPTX.matchExtension(newName)) || (FileExtension.CPT.matchExtension(oldName) && FileExtension.CPT.matchExtension(newName))); + } + + /** + * cptx另存为cpt需要修改报表引擎属性 + **/ + private static boolean setFrEngineAttr(JTemplate jTemplate){ + WorkSheet workSheet = gainWorkSheet(jTemplate.getTarget()); + if (workSheet == null){ + return false; + }else { + LayerReportAttr layerReportAttr = workSheet.getLayerReportAttr(); + if (layerReportAttr == null){ + layerReportAttr = new LayerReportAttr(); + workSheet.setLayerReportAttr(layerReportAttr); + } + layerReportAttr.setClientPaging(true); + layerReportAttr.setEngineState(0); + return true; + } + } + + /** + * 是否启用了新引擎的判断 + * cptx自动走新引擎(非兼容模式),cpt需要进行设置 + * */ + public static boolean isEngineXEnable(Object workBook, String fileName){ + WorkSheet workSheet = gainWorkSheet(workBook); + LayerReportAttr layerReportAttr = gainLayerReportAttr(workSheet); + return isEngineXEnable(layerReportAttr, fileName); + } + + private static LayerReportAttr gainLayerReportAttr(WorkSheet workSheet){ + if (workSheet != null){ + LayerReportAttr layerReportAttr = workSheet.getLayerReportAttr(); + return layerReportAttr; + } else { + return null; + } + } + + private static WorkSheet gainWorkSheet(Object workBook){ + if (workBook == null || !(workBook instanceof TemplateWorkBook)){ + return null; + } + Report report = ((TemplateWorkBook) workBook).getReport(0); + return report instanceof WorkSheet ? (WorkSheet)report : null; + } + + private static boolean isEngineXEnable(LayerReportAttr layerReportAttr, String fileName){ + return (layerReportAttr!= null && layerReportAttr.isClientPaging() && layerReportAttr.getEngineState() == LayerReportAttr.ENGINE_X) || FileExtension.CPTX.matchExtension(fileName); + } +} diff --git a/designer-base/src/main/java/com/fr/nx/app/designer/utils/CptCompileUtil.java b/designer-base/src/main/java/com/fr/nx/app/designer/utils/CptCompileUtil.java new file mode 100644 index 000000000..36c184670 --- /dev/null +++ b/designer-base/src/main/java/com/fr/nx/app/designer/utils/CptCompileUtil.java @@ -0,0 +1,153 @@ +package com.fr.nx.app.designer.utils; + +import com.fr.base.extension.FileExtension; +import com.fr.design.mainframe.JTemplate; +import com.fr.file.FILE; +import com.fr.file.FileNodeFILE; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.main.impl.WorkBook; +import com.fr.nx.app.designer.cptx.io.DesignReadWritableProvider; +import com.fr.nx.app.designer.monitor.DesignerMetricRecorder; +import com.fr.nx.app.designer.toolbar.TransformResult; +import com.fr.nx.app.designer.toolbar.TransformResultInfo; +import com.fr.nx.compile.CompileStatus; +import com.fr.nx.compile.ReportCompiler; +import com.fr.nx.compile.adapter.LegacyWorkBookAdapter; +import com.fr.nx.compile.util.ReportCompileUtils; +import com.fr.nx.cptx.CptxIOManager; +import com.fr.nx.cptx.cache.CptxTemplatePool; +import com.fr.nx.cptx.entry.CptxTemplate; +import com.fr.nx.cptx.io.handle.CptxTemplateHandle; +import com.fr.nx.cptx.monitor.CompileMonitorHandler; +import com.fr.nx.cptx.utils.CptxFileUtils; +import com.fr.nx.data.layer.LayerItem; +import com.fr.nx.data.layer.LayerProps; +import com.fr.nx.template.compile.CompiledReport; + +import java.io.OutputStream; + + +public class CptCompileUtil { + public static void compile(JTemplate jtemplate) { + if (jtemplate == null || jtemplate.getEditingFILE() == null) { + return; + } + FILE file = jtemplate.getEditingFILE(); + String path = file.getPath(); + Object target = jtemplate.getTarget(); + /* + * 如果是cpt并且引擎设置正确,执行预编译,如果是cptx文件也执行预编译。在JStreamWork中,保存和另存为流程都进行了重新编译。 + * 但是由于之前的DefaultTemplateResource.saveTemplate的原因导致JStreamWork::saveFile()不能执行--cptx的保存不能进行预编译, + * 应该是流程的误改动,这里改回来,保存时仍然执行预编译。 + * 预编译本不应该受引擎模式的影响,但是cpt文件在设置为新引擎后是需要进行编译的 + * */ + + if (!CptAndCptxCompatibilityUtil.isEngineXEnable(target, path)){ + return; + } + WorkBook workbook = (WorkBook) jtemplate.getTarget(); + TransformResultInfo resultInfo = compile0(workbook, file); + unSupportLog(resultInfo); + + } + + private static TransformResultInfo compile0(WorkBook workbook, FILE file) { + if (!(file instanceof FileNodeFILE)) { + try { + OutputStream outputStream = file.asOutputStream(); + workbook.export(outputStream); + return TransformResultInfo.generateResult(TransformResult.SUCCESS).saved(true); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return TransformResultInfo.generateResult(TransformResult.FAILED).saved(false); + } + } + boolean saved; + CompiledReport report = null; + CompileStatus compileStatus = CompileStatus.SUCCEED; + if (workbook == null || file == null) { + return TransformResultInfo + .generateResult(TransformResult.FAILED, "work and file must not be null") + .saved(false); + } + String failMessage = null; + // 编译 + ReportCompiler compiler; + try { + compiler = new ReportCompiler(new LegacyWorkBookAdapter(workbook)); + long startTime = System.currentTimeMillis(); + compiler.compile(); + report = compiler.getCompiledReport(); + // 折叠树埋点 + LayerProps props = ReportCompileUtils.getLayerProps(report); + LayerItem[] items; + if (props != null && (items = props.getLayerItems()) != null) { + CompileMonitorHandler.submitTreeCompileFocusPoint( + startTime, file.getPath(), items.length, + props.getExpandLayer(), true + ); + } + compileStatus = compiler.getStatus(); + failMessage = compiler.getFailMessage(); + long endTime = System.currentTimeMillis(); + CompileMonitorHandler.submitCompileMessage(startTime, endTime, file.getPath(), ""); + if (compileStatus != CompileStatus.SUCCEED) { + DesignerMetricRecorder.submitUnSupportTransform( + TransformResult.UNSUPPORT, + workbook.getTemplateID(), + file.getName(), + compileStatus == CompileStatus.FAILED_UNSUPPORT ? failMessage : null + ); + } + } catch (Exception exception) { + String templateID = workbook.getTemplateID(); + String fileName = file.getName(); + DesignerMetricRecorder.submitFailedTransform(TransformResult.FAILED, templateID, fileName, exception); + FineLoggerFactory.getLogger().error(exception.getMessage(), exception); + } + + // 构建编译结果,当前的 cptx template 是未经反序列化钩子处理过的 cptx 模版对象,不能直接用于模版预览 + CptxTemplate template = CptxIOManager.createCptxTemplate(workbook, report, compileStatus, failMessage); + // 保存 + DesignReadWritableProvider cptx = new DesignReadWritableProvider(file); + CptxTemplateHandle handle = CptxIOManager.create(template, cptx); + try { + saved = handle.save(); + } catch (Exception exception) { + // 存储cptx格式报错或者失败 + FineLoggerFactory.getLogger().error(exception.getMessage(), exception); + DesignerMetricRecorder.submitFailedTransform(TransformResult.FAILED, workbook.getTemplateID(), file.getName(), exception); + return TransformResultInfo.generateResult(TransformResult.FAILED, failMessage).saved(false); + } + // 读取可 web 预览模版并缓存 + try { + CptxTemplate previewCptxTemplate = CptxIOManager.open(cptx).getTemplate(); + CptxTemplatePool.getInstance().addCptxTemplate(CptxFileUtils.getFormatPath(file.getPath()), previewCptxTemplate); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + if (report == null) { + // 编译报错或者失败 + return TransformResultInfo.generateResult(TransformResult.FAILED, failMessage).saved(saved); + } + return TransformResultInfo.generateResult(TransformResult.parse(compileStatus), failMessage).saved(saved); + } + + private static boolean needDoAfterCompile(TransformResult result) { + return ComparatorUtils.equals(TransformResult.SUCCESS, result) + || ComparatorUtils.equals(TransformResult.UNSUPPORT, result); + } + + private static void unSupportLog(TransformResultInfo transformResultInfo){ + TransformResult result = transformResultInfo.getResult(); + //这里只打印模板转换不支持的信息,没有打印模板转换失败的信息 + if (result.equals(TransformResult.UNSUPPORT)){ + FineLoggerFactory.getLogger().error(transformResultInfo.getTransformLog()); + } + } + + private static boolean isUnSupportFileType(String path){ + return FileExtension.CPT.matchExtension(path) || FileExtension.CPTX.matchExtension(path); + } +} diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties index ef851ffe3..b69ede5ea 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties @@ -7,4 +7,5 @@ com.fr.env.RemoteEnvPane.dialog=458*132 com.fr.design.version.check.dialog=490*95 com.fr.design.version.detail.label=750*30 com.fr.design.version.detail.dialog=900*500 +com.fr.env.SyncFailedPluginsDialog.messageWithLink=316*36 com.fr.design.web.pane.text.field=450*20 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties index 379c25744..7d09dee4d 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties @@ -6,4 +6,5 @@ com.fr.env.RemoteEnvPane.dialog=458*132 com.fr.design.version.check.dialog=430*95 com.fr.design.version.detail.label=650*30 com.fr.design.version.detail.dialog=800*500 +com.fr.env.SyncFailedPluginsDialog.messageWithLink=316*36 com.fr.design.web.pane.text.field=400*20 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties index 62ee87a7c..28823bf1a 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties @@ -6,4 +6,5 @@ com.fr.env.RemoteEnvPane.dialog=458*132 com.fr.design.version.check.dialog=450*95 com.fr.design.version.detail.label=700*30 com.fr.design.version.detail.dialog=850*500 +com.fr.env.SyncFailedPluginsDialog.messageWithLink=316*36 com.fr.design.web.pane.text.field=450*20 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties index fff64947d..56998f7f7 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties @@ -7,4 +7,5 @@ com.fr.env.RemoteEnvPane.dialog=308*132 com.fr.design.version.check.dialog=230*95 com.fr.design.version.detail.label=450*30 com.fr.design.version.detail.dialog=600*500 +com.fr.env.SyncFailedPluginsDialog.messageWithLink=316*20 com.fr.design.web.pane.text.field=450*20 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties index 4b2de3f02..58e6ae121 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties @@ -6,4 +6,5 @@ com.fr.env.RemoteEnvPane.dialog=308*132 com.fr.design.version.check.dialog=230*95 com.fr.design.version.detail.label=450*30 com.fr.design.version.detail.dialog=600*500 +com.fr.env.SyncFailedPluginsDialog.messageWithLink=316*20 com.fr.design.web.pane.text.field=450*20 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/images/transparent_background.png b/designer-base/src/main/resources/com/fr/design/images/transparent_background.png index cfb233f46..4f942536f 100644 Binary files a/designer-base/src/main/resources/com/fr/design/images/transparent_background.png and b/designer-base/src/main/resources/com/fr/design/images/transparent_background.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/arrow_down.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/arrow_down.png new file mode 100644 index 000000000..cf65b3bc4 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/arrow_down.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/arrow_right.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/arrow_right.png new file mode 100644 index 000000000..a1ac42cfe Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/arrow_right.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/close.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/close.png new file mode 100644 index 000000000..6f17a8e1c Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/close.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_all.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_all.png new file mode 100644 index 000000000..c696cba4d Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_all.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_none.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_none.png new file mode 100644 index 000000000..4c6c6f2bb Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_none.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_some.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_some.png new file mode 100644 index 000000000..b3443318b Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_some.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/guide.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/guide.png new file mode 100644 index 000000000..ef5a19783 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/guide.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/loading.gif b/designer-base/src/main/resources/com/fr/design/mainframe/guide/loading.gif new file mode 100644 index 000000000..90d13277a Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/loading.gif differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/success.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/success.png new file mode 100644 index 000000000..efd7a04f4 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/success.png differ diff --git a/designer-chart/src/main/java/com/fr/design/ChartTypeInterfaceManager.java b/designer-chart/src/main/java/com/fr/design/ChartTypeInterfaceManager.java index 8600a8c14..2d54fc818 100644 --- a/designer-chart/src/main/java/com/fr/design/ChartTypeInterfaceManager.java +++ b/designer-chart/src/main/java/com/fr/design/ChartTypeInterfaceManager.java @@ -149,7 +149,7 @@ public class ChartTypeInterfaceManager implements ExtraChartDesignClassManagerPr public static WidgetOption[] initWidgetOption() { - String[] chartIDs = ChartTypeManager.getInstance().getAllChartIDs(); + String[] chartIDs = ChartTypeManager.getInstance().getChartIDs4Create(); ChartWidgetOption[] child = new ChartWidgetOption[chartIDs.length]; int index = 0; diff --git a/designer-chart/src/main/java/com/fr/design/chart/ChartTypePane.java b/designer-chart/src/main/java/com/fr/design/chart/ChartTypePane.java index a5937c1d9..d31cd3208 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/ChartTypePane.java +++ b/designer-chart/src/main/java/com/fr/design/chart/ChartTypePane.java @@ -31,7 +31,7 @@ import java.awt.Component; public class ChartTypePane extends ChartCommonWizardPane implements CallbackEvent { private static final long serialVersionUID = -1175602484968520546L; - private String[] chartIDs = ChartTypeManager.getInstanceWithCheck().getAllChartIDs(); + private String[] chartIDs = ChartTypeManager.getInstanceWithCheck().getChartIDs4Create(); private JList mainTypeList = null; private JList iconViewList = null; diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java index 90b0e8805..2d4d5fef6 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java @@ -55,6 +55,8 @@ public class ChartPropertyPane extends BaseChartPropertyPane { chartEditPane.setContainer(container); currentID = plotID; resetChartEditPane(); + } else { + chartEditPane.resetLastChartCollection(); } } diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java index d6acb929a..70b7130f1 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java @@ -118,6 +118,10 @@ public class ChartEditPane extends BasicPane implements AttributeChange, Prepare this.listenerList.remove(ChartEditPaneActionListener.class, l); } + public void resetLastChartCollection() { + this.lastCollection = null; + } + private void fireAttributeChange(ChartCollection chartCollection) { // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypePane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypePane.java index 985ee28af..2eea49f16 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypePane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypePane.java @@ -4,6 +4,7 @@ import com.fr.chart.chartattr.ChartCollection; import com.fr.chart.charttypes.ChartTypeManager; import com.fr.chartx.attr.ChartProvider; import com.fr.design.ChartTypeInterfaceManager; +import com.fr.design.base.mode.DesignModeContext; import com.fr.design.beans.FurtherBasicBeanPane; import com.fr.design.dialog.BasicScrollPane; import com.fr.design.dialog.DialogActionAdapter; @@ -18,6 +19,7 @@ import com.fr.design.mainframe.chart.gui.item.FlexibleComboBox; import com.fr.design.mainframe.chart.gui.item.ItemEventType; import com.fr.design.mainframe.chart.gui.type.AbstractChartTypePane; import com.fr.design.mainframe.chart.mode.ChartEditContext; +import com.fr.design.mainframe.chart.mode.ChartEditMode; import com.fr.design.module.DesignModuleFactory; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; @@ -173,7 +175,7 @@ public class ChartTypePane extends AbstractChartAttrPane { Map>> allChartTypePane, ActionListener autoButtonListener) { - String[] chartIDs = ChartTypeManager.getInstance().getAllChartIDsIncludeDisabled(); + String[] chartIDs = ChartTypeManager.getInstance().getAllChartIDs(); for (String id : chartIDs) { @@ -288,7 +290,9 @@ public class ChartTypePane extends AbstractChartAttrPane { Map.Entry> entry = iterator.next(); String plotID = entry.getKey(); if (ignore || ChartTypeManager.enabledChart(plotID)) { - cards.add(entry.getValue()); + if (ChartTypeManager.getInstance().isShowInDesigner(plotID)) { + cards.add(entry.getValue()); + } } } @@ -310,7 +314,9 @@ public class ChartTypePane extends AbstractChartAttrPane { //第一步就是重构cards cards.clear(); - if (enabledChart) { + if (ChartEditContext.duchampMode()) { + addOnePlotIDCards(priority, chartID); + } else if (enabledChart) { if (collection.getChartCount() == 1) { addAllCards(); } else { diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java index 78be16ad5..dc72b9022 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java @@ -471,7 +471,11 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { } protected Component[][] createToolBarComponents() { - return new Component[][]{ + return ChartEditContext.duchampMode() ? new Component[][]{ + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Content")), isSort}, + new Component[]{null, fullScreenDisplay}, + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Layout")), collapse}, + } : new Component[][]{ new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Content")), isSort}, new Component[]{null, exportImages}, new Component[]{null, fullScreenDisplay}, @@ -480,7 +484,10 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { } protected Component[][] createToolBarComponentsWithOutSort() { - return new Component[][]{ + return ChartEditContext.duchampMode() ? new Component[][]{ + new Component[]{null, fullScreenDisplay}, + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Layout")), collapse} + } : new Component[][]{ new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Content")), exportImages}, new Component[]{null, fullScreenDisplay}, new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Layout")), collapse} diff --git a/designer-chart/src/main/java/com/fr/van/chart/drillmap/designer/other/VanChartDrillMapInteractivePane.java b/designer-chart/src/main/java/com/fr/van/chart/drillmap/designer/other/VanChartDrillMapInteractivePane.java index 80962fd86..7ada5f9c5 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/drillmap/designer/other/VanChartDrillMapInteractivePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/drillmap/designer/other/VanChartDrillMapInteractivePane.java @@ -100,7 +100,12 @@ public class VanChartDrillMapInteractivePane extends VanChartInteractivePaneWith double f = TableLayout.FILL; double[] columnSize = {f}; double[] rowSize = {p, p, p, p, p, p}; - Component[][] components = new Component[][]{ + Component[][] components = ChartEditContext.duchampMode() ? new Component[][]{ + new Component[]{null}, + new Component[]{createTitlePane(Toolkit.i18nText("Fine-Design_Chart_Character"), textAttrPane)}, + new Component[]{backgroundPane}, + new Component[]{selectBackgroundPane} + } : new Component[][]{ new Component[]{null}, new Component[]{createTitlePane(Toolkit.i18nText("Fine-Design_Chart_Character"), textAttrPane)}, new Component[]{backgroundPane}, diff --git a/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeSeriesPane.java b/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeSeriesPane.java index 49e4391b5..566a1a0a6 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeSeriesPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeSeriesPane.java @@ -16,6 +16,7 @@ import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.chart.gui.ChartStylePane; import com.fr.design.mainframe.chart.gui.style.series.ColorPickerPaneWithMaxMin; import com.fr.design.mainframe.chart.gui.style.series.UIColorPickerPane; +import com.fr.design.mainframe.chart.mode.ChartEditContext; import com.fr.design.style.color.ColorSelectBox; import com.fr.general.ComparatorUtils; import com.fr.plugin.chart.attr.GaugeDetailStyle; @@ -198,7 +199,9 @@ public class VanChartGaugeSeriesPane extends VanChartMultiColorSeriesPane { if (attrLabelDetail == null || attrLabelDetail.getTextAttr() == null) { return; } - attrLabelDetail.getTextAttr().setFRFont(VanChartGaugePlot.THERMOMETER_LABEL_FONT); + if (!ChartEditContext.duchampMode()) { + attrLabelDetail.getTextAttr().setFRFont(VanChartGaugePlot.THERMOMETER_LABEL_FONT); + } if (gaugeLayout.getSelectedIndex() == 0) { attrLabel.getAttrLabelDetail().setPosition(Constants.LEFT); attrLabel.getGaugeValueLabelDetail().setPosition(Constants.LEFT); diff --git a/designer-form/src/main/java/com/fr/design/actions/FormFitAttrAction.java b/designer-form/src/main/java/com/fr/design/actions/FormFitAttrAction.java new file mode 100644 index 000000000..e69de29bb diff --git a/designer-form/src/main/java/com/fr/design/actions/NewFormAction.java b/designer-form/src/main/java/com/fr/design/actions/NewFormAction.java index c867be8d2..5ce51b673 100644 --- a/designer-form/src/main/java/com/fr/design/actions/NewFormAction.java +++ b/designer-form/src/main/java/com/fr/design/actions/NewFormAction.java @@ -1,13 +1,8 @@ package com.fr.design.actions; -import com.fr.base.svg.IconUtils; -import com.fr.design.mainframe.BaseJForm; -import com.fr.design.mainframe.DesignerContext; -import com.fr.design.mainframe.JTemplate; import com.fr.design.menu.MenuKeySet; - -import com.fr.stable.bridge.StableFactory; +import com.fr.design.widget.ui.designer.NewFormPane; import javax.swing.KeyStroke; import java.awt.event.ActionEvent; @@ -31,8 +26,7 @@ public class NewFormAction extends UpdateAction { * @param e 事件 */ public void actionPerformed(ActionEvent e) { - BaseJForm jform = StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, BaseJForm.class); - DesignerContext.getDesignerFrame().addAndActivateJTemplate((JTemplate) jform); + new NewFormPane().showWindow(); } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/LayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/LayoutAdapter.java index f10b877e2..438699b86 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/LayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/LayoutAdapter.java @@ -1,7 +1,12 @@ package com.fr.design.designer.beans; import com.fr.design.beans.GroupModel; +import com.fr.design.designer.beans.adapters.layout.DefaultDesignerBaseOperate; +import com.fr.design.designer.beans.adapters.layout.DesignerBaseOperate; +import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.treeview.DefaultXCreatorTreeCellRender; +import com.fr.design.designer.treeview.XCreatorTreeCellRender; /** * 该接口是LayoutManager的BeanInfo类。标准Java平台没有提供布局管理器的BeanInfo类, @@ -50,11 +55,11 @@ public interface LayoutAdapter { * @param creator 被添加的新组件 * @param x 添加的位置x,该位置是相对于container的 * @param y 添加的位置y,该位置是相对于container的 - * @param accept 是否添加新组件 + * @param accept 是否添加新组件 * @return 是否添加成功,成功返回true,否则false */ boolean addBean(XCreator creator, int x, int y, boolean accept); - + /** * 返回该布局管理适配器的Painter,为容器提供放置位置的标识。 */ @@ -104,4 +109,36 @@ public interface LayoutAdapter { * @param initHeight 组件之前高度 */ void removeBean(XCreator creator, int initWidth, int initHeight); + + /** + * 获取布局下控件树render + * @param creator + * @return + */ + default XCreatorTreeCellRender getLayoutTreeCellRender(XCreator creator) { + return new DefaultXCreatorTreeCellRender(creator); + } + + /** + * 获取布局下支持的设计器基本操作 + * @return + */ + default DesignerBaseOperate getDesignerBaseOperate() { + return new DefaultDesignerBaseOperate(); + } + + /** + * 是否支持修改间距 + * @return + */ + default boolean supportModifyInsert() { + return true; + } + + void dragStart(XCreator xCreator, SelectionModel selectionModel); + + default void dragOver(XCreator xCreator, SelectionModel selectionModel, int x, int y) { + + }; + } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/PredefinedLayout.java b/designer-form/src/main/java/com/fr/design/designer/beans/PredefinedLayout.java new file mode 100644 index 000000000..ba184e570 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/PredefinedLayout.java @@ -0,0 +1,35 @@ +package com.fr.design.designer.beans; + +import java.io.Serializable; + +public class PredefinedLayout implements Serializable { + private static final String IMAGE_PATH = "/com/fr/design/form/layouts/images/"; + private static final String TEMPLATE_PATH = "/com/fr/design/form/layouts/templates/"; + private String template; + private String realStyle; + private String simpleStyle; + + public String getTemplate() { + return TEMPLATE_PATH + template; + } + + public void setTemplate(String template) { + this.template = template; + } + + public String getRealStyle() { + return IMAGE_PATH + realStyle; + } + + public void setRealStyle(String realStyle) { + this.realStyle = realStyle; + } + + public String getSimpleStyle() { + return IMAGE_PATH + simpleStyle; + } + + public void setSimpleStyle(String simpleStyle) { + this.simpleStyle = simpleStyle; + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java index 94c84a87d..7e1329b93 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java @@ -2,7 +2,6 @@ package com.fr.design.designer.beans.actions; import com.fr.design.base.mode.DesignModeContext; -import com.fr.design.designer.beans.actions.behavior.ComponentEnable; import com.fr.design.designer.beans.actions.behavior.CutableEnable; import com.fr.design.mainframe.FormDesigner; diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java index c2fec8f39..75a744251 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java @@ -41,6 +41,14 @@ public class FormDeleteAction extends FormWidgetEditAction { return comp; } + @Override + public JComponent createToolBarComponentByName(String componentName) { + JComponent comp = super.createToolBarComponentByName(componentName); + // 除了 BACKSPACE 之外,DELETE 键也要能删除(直接在此处添加绑定,没有按钮提示) + comp.registerKeyboardAction(this, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); + return comp; + } + /** * 删除 * diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/PasteAction.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/PasteAction.java index ef35097b2..00e229e68 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/actions/PasteAction.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/PasteAction.java @@ -1,6 +1,7 @@ package com.fr.design.designer.beans.actions; import com.fr.design.base.mode.DesignModeContext; +import com.fr.design.designer.beans.actions.behavior.PasteEnable; import com.fr.design.mainframe.FormDesigner; import javax.swing.KeyStroke; @@ -15,6 +16,7 @@ public class PasteAction extends FormWidgetEditAction { this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_M_Edit_Paste")); this.setMnemonic('P'); this.setSmallIcon("/com/fr/design/images/m_edit/paste"); + this.setUpdateBehavior(new PasteEnable()); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER)); } @@ -22,10 +24,5 @@ public class PasteAction extends FormWidgetEditAction { public boolean executeActionReturnUndoRecordNeeded() { return DesignModeContext.doPaste(getEditingComponent()); } - - @Override - public void update() { - this.setEnabled(true); - } - + } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/PasteEnable.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/PasteEnable.java new file mode 100644 index 000000000..47c5c5af1 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/PasteEnable.java @@ -0,0 +1,16 @@ +package com.fr.design.designer.beans.actions.behavior; + +import com.fr.design.designer.beans.actions.FormWidgetEditAction; +import com.fr.design.mainframe.FormDesigner; + +public class PasteEnable implements UpdateBehavior { + @Override + public void doUpdate(FormWidgetEditAction action) { + FormDesigner designer = action.getEditingComponent(); + if (designer == null) { + action.setEnabled(false); + return; + } + action.setEnabled(designer.isCurrentComponentPastable()); + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/component/CompositeComponentAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/component/CompositeComponentAdapter.java index 5fdc8f3de..cb7a7a620 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/component/CompositeComponentAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/component/CompositeComponentAdapter.java @@ -29,6 +29,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; import java.beans.IntrospectionException; import java.util.ArrayList; import java.util.Collections; @@ -64,13 +65,15 @@ public class CompositeComponentAdapter implements ComponentAdapter { @Override public void paintComponentMascot(Graphics g) { - //自适应交叉点渲染有点问题,拖拽的控件设置成半透明 - Graphics2D g2d = (Graphics2D) g; - AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,.5f); - g2d.setComposite(composite); - xCreator.paint(g2d); + //自适应交叉点渲染有点问题,拖拽的控件设置成半透明 + Graphics2D g2d = (Graphics2D) g; + AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f); + g2d.setComposite(composite); + BufferedImage im = new BufferedImage(xCreator.getWidth(), xCreator.getHeight(), BufferedImage.TYPE_INT_ARGB); + xCreator.paint(im.getGraphics()); + g.drawImage(im, 0, 0, xCreator.initEditorSize().width - 1, xCreator.initEditorSize().height - 1, null); g.setColor(XCreatorConstants.RESIZE_BOX_BORDER_COLOR); - g.drawRect(0, 0, xCreator.getWidth() - 1, xCreator.getHeight() - 1); + g.drawRect(0, 0, xCreator.initEditorSize().width - 1, xCreator.initEditorSize().height - 1); } @Override diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/AbstractLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/AbstractLayoutAdapter.java index e9851a7e8..98b6c8855 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/AbstractLayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/AbstractLayoutAdapter.java @@ -4,6 +4,7 @@ import com.fr.design.beans.GroupModel; import com.fr.design.designer.beans.ConstraintsGroupModel; import com.fr.design.designer.beans.HoverPainter; import com.fr.design.designer.beans.LayoutAdapter; +import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.beans.painters.NullPainter; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XLayoutContainer; @@ -203,4 +204,11 @@ public abstract class AbstractLayoutAdapter implements LayoutAdapter { public XLayoutContainer getContainer() { return this.container; } + + public void dragStart(XCreator xCreator, SelectionModel selectionModel){ + selectionModel.removeCreator(xCreator, xCreator.getWidth(), xCreator.getHeight()); + selectionModel.setSelectedCreator(container); + } + + } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/DefaultDesignerBaseOperate.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/DefaultDesignerBaseOperate.java new file mode 100644 index 000000000..f3ec95939 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/DefaultDesignerBaseOperate.java @@ -0,0 +1,23 @@ +package com.fr.design.designer.beans.adapters.layout; + +public class DefaultDesignerBaseOperate implements DesignerBaseOperate{ + @Override + public boolean supportCopyAction() { + return true; + } + + @Override + public boolean supportCutAction() { + return true; + } + + @Override + public boolean supportPasteAction() { + return true; + } + + @Override + public boolean supportDeleteAction() { + return true; + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/DesignerBaseOperate.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/DesignerBaseOperate.java new file mode 100644 index 000000000..410daf8b5 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/DesignerBaseOperate.java @@ -0,0 +1,33 @@ +package com.fr.design.designer.beans.adapters.layout; + +public interface DesignerBaseOperate { + + /** + * 是否支持复制 + * + * @return boolean + */ + boolean supportCopyAction(); + + /** + * 是否支持剪切 + * + * @return boolean + */ + boolean supportCutAction(); + + /** + * 是否支持粘贴 + * + * @return boolean + */ + boolean supportPasteAction(); + + /** + * 是否支持删除 + * + * @return boolean + */ + boolean supportDeleteAction(); + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java index c893268ba..84013aadf 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java @@ -7,7 +7,8 @@ import com.fr.design.ExtraDesignClassManager; import com.fr.design.beans.GroupModel; import com.fr.design.designer.beans.ConstraintsGroupModel; import com.fr.design.designer.beans.HoverPainter; -import com.fr.design.designer.beans.painters.FRFitLayoutPainter; +import com.fr.design.designer.beans.LayoutAdapter; +import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XLayoutContainer; @@ -19,6 +20,7 @@ import com.fr.design.designer.creator.cardlayout.XWCardTitleLayout; import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; import com.fr.design.designer.properties.FRFitLayoutConstraints; import com.fr.design.designer.properties.FRFitLayoutPropertiesGroupModel; +import com.fr.design.designer.treeview.XCreatorTreeCellRender; import com.fr.design.fun.FormWidgetOptionProvider; import com.fr.design.utils.ComponentUtils; import com.fr.form.ui.LayoutBorderStyle; @@ -43,8 +45,6 @@ import java.util.Set; * @date 2014-6-24 */ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { - - public static final String WIDGETPANEICONPATH = "/com/fr/web/images/form/resources/layout_absolute.png"; private static final int DEPENDING_SCOPE = 3; private HoverPainter painter; //区分拖拽和编辑宽高 @@ -58,6 +58,8 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { isEdit = edit; } + private LayoutAdapter frLayoutState; + /** * 构造函数 * @@ -65,10 +67,18 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { */ public FRFitLayoutAdapter(XLayoutContainer container) { super(container); - painter = new FRFitLayoutPainter(container); initMinSize(); + this.frLayoutState = new FRNoFixLayoutAdapter(this, container, minHeight); + painter = this.frLayoutState.getPainter(); } + + public void setFrLayoutState(LayoutAdapter frLayoutState){ + this.frLayoutState = frLayoutState; + painter = this.frLayoutState.getPainter(); + } + + private void initMinSize() { XWFitLayout layout = (XWFitLayout) container; minWidth = layout.getActualMinWidth(); @@ -100,16 +110,7 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { */ @Override public void addComp(XCreator child, int x, int y) { - fix(child, x, y); - if (child.shouldScaleCreator() || child.hasTitleStyle()) { - addParentCreator(child); - } else { - container.add(child, child.toData().getWidgetName()); - } - XWFitLayout layout = (XWFitLayout) container; - // 更新对应的BoundsWidget - layout.updateBoundsWidget(); - updateCreatorBackBound(); + frLayoutState.addBean(child, x, y); } public void updateCreatorBackBound() { @@ -130,11 +131,6 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { } - private void addParentCreator(XCreator child) { - XLayoutContainer parentPanel = child.initCreatorWrapper(minHeight); - container.add(parentPanel, child.toData().getWidgetName()); - } - /** * 能否对应位置放置当前组件 * @@ -164,8 +160,10 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { //布局控件要先判断是不是可编辑 XLayoutContainer topLayout = XCreatorUtils.getHotspotContainer((XCreator) comp).getTopLayout(); - boolean access = topLayout != null && !isMatchEdge && !topLayout.isEditable() && !topLayout.acceptType(XWAbsoluteLayout.class) && !isExtraContainer(comp) && !topLayout.isDragInAble(); - if (access) { + boolean access = topLayout != null && !isMatchEdge && !topLayout.acceptType(XWAbsoluteLayout.class) && !isExtraContainer(comp) && !topLayout.isDragInAble(); + //topLayout.getParent() != container说明当前增加的组件所在容器是嵌套在外部的自适应容器内部的,此时需要判断增加组件所在容器是否可编辑,不可编辑的话就直接返回 false + //否则说明就是往当前自适应容器内部添加组件,不需要判断其是否可编辑 + if (access && (topLayout.getParent() != container && !topLayout.isEditable())) { return false; } @@ -206,7 +204,7 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { * @param y 纵坐标 * @return 是否在组件边缘 */ - public boolean matchEdge(int x, int y) { + private boolean matchEdge(int x, int y) { if (intersectsEdge(x, y, container)) { //寻找最近的fit, 在边缘地段添加的控件, 将其送给该fit XLayoutContainer parent = container.findNearestFit(); @@ -760,15 +758,9 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { super.fixTrisect(currentComp, child, x, y); } - /** - * 删除组件或者重新拖动时,其它组件重新计算位置大小 - */ - protected void delete(XCreator creator, int creatorWidth, int creatorHeight) { - int x = creator.getX(); - int y = creator.getY(); - recalculateChildrenSize(x, y, creatorWidth, creatorHeight, true); + public void removeBean(XCreator creator, int creatorWidth, int creatorHeight) { + frLayoutState.removeBean(creator, creatorWidth, creatorHeight); } - /** * 重新计算内部组件大小 * @@ -1216,11 +1208,11 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { /** * 删除或拉伸上边框 调整上方的组件位置大小 */ - protected boolean calculateUpRelatComponent(int objHeight) { + private boolean calculateUpRelatComponent(int objHeight) { return calculateUpRelatComponent(objHeight, false); } - protected boolean calculateUpRelatComponent(int objHeight, boolean isDel) { + private boolean calculateUpRelatComponent(int objHeight, boolean isDel) { if (!isDel && isBeyondAdjustHeightScope(objHeight)) { return false; } @@ -1248,4 +1240,25 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { public ConstraintsGroupModel getLayoutConstraints(XCreator creator) { return new FRFitLayoutConstraints((XWFitLayout) container, creator); } + + public XCreatorTreeCellRender getLayoutTreeCellRender(XCreator creator){ + return frLayoutState.getLayoutTreeCellRender(creator); + } + + @Override + public DesignerBaseOperate getDesignerBaseOperate() { + return frLayoutState.getDesignerBaseOperate(); + } + + public boolean supportModifyInsert() { + return frLayoutState.supportModifyInsert(); + } + + public void dragStart(XCreator xCreator, SelectionModel selectionModel){ + frLayoutState.dragStart(xCreator, selectionModel); + } + + public void dragOver(XCreator xCreator, SelectionModel selectionModel,int x, int y) { + frLayoutState.dragOver(xCreator, selectionModel,x,y); + }; } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFixLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFixLayoutAdapter.java new file mode 100644 index 000000000..d649c5e30 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFixLayoutAdapter.java @@ -0,0 +1,138 @@ +package com.fr.design.designer.beans.adapters.layout; + +import com.fr.base.svg.IconUtils; +import com.fr.design.designer.beans.HoverPainter; +import com.fr.design.designer.beans.models.ModelUtil; +import com.fr.design.designer.beans.models.SelectionModel; +import com.fr.design.designer.beans.painters.FRFixLayoutPainter; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XOccupiedLayout; +import com.fr.design.designer.treeview.DefaultXCreatorTreeCellRender; +import com.fr.design.designer.treeview.XCreatorTreeCellRender; +import com.fr.design.mainframe.FormDesigner; +import com.fr.design.mainframe.WidgetPropertyPane; +import com.fr.form.ui.container.OccupiedLayout; +import javax.swing.Icon; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; + +public class FRFixLayoutAdapter extends AbstractLayoutAdapter { + private static final Icon OCCUPIED_ICON = IconUtils.readIcon("/com/fr/design/form/images/occupied_layout.png"); + + public FRFixLayoutAdapter( XLayoutContainer container) { + super(container); + } + + public void addComp(XCreator child, int x, int y) { + Component component = container.getComponentAt(x, y); + if (component == container) { + return; + } + child.setLocation(component.getX(), component.getY()); + child.setSize(component.getWidth(), component.getHeight()); + if (child.shouldScaleCreator() || child.hasTitleStyle()) { + XLayoutContainer parentPanel = child.initCreatorWrapper(21); + container.replaceXcreator(parentPanel, (XCreator) component); + } else { + container.replaceXcreator(child, (XCreator) component); + } + if (child.getBackupRectangle() != null && child.getParent() == container) { + Component origin = container.getComponentAt(child.getBackupRectangle().x + 5, child.getBackupRectangle().y + 5); + if (origin == container) { + return; + } + if (origin instanceof XOccupiedLayout) { + ((XOccupiedLayout) origin).getLayoutAdapter().addBean((XCreator) component, child.getBackupRectangle().x + 5, child.getBackupRectangle().y + 5); + } + } + } + + @Override + public void delete(XCreator creator, int creatorWidth, int creatorHeight) { + //固定布局下不支持移除占位块组件 + if (creator.acceptType(XOccupiedLayout.class)){ + return; + } + OccupiedLayout occupiedLayout = new OccupiedLayout(); + FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + XOccupiedLayout xoccupiedLayout = new XOccupiedLayout(occupiedLayout, new Dimension()); + ModelUtil.renameWidgetName(formDesigner.getTarget(), xoccupiedLayout); + xoccupiedLayout.setLocation(creator.getX(), creator.getY()); + xoccupiedLayout.setSize(creatorWidth, creatorHeight); + container.replaceXcreator(xoccupiedLayout,creator); + } + + + @Override + public XCreatorTreeCellRender getLayoutTreeCellRender(XCreator creator) { + return new DefaultXCreatorTreeCellRender(creator) { + @Override + public void paint(Graphics g, Component c) { + if (!getxCreator().acceptType(XOccupiedLayout.class)) { + OCCUPIED_ICON.paintIcon(c, g, 0, 0); + } + super.paint(g, c); + } + }; + } + + @Override + public boolean supportModifyInsert() { + return false; + } + + @Override + public DesignerBaseOperate getDesignerBaseOperate() { + return new DesignerBaseOperate() { + @Override + public boolean supportCopyAction() { + return false; + } + + @Override + public boolean supportCutAction() { + return false; + } + + @Override + public boolean supportPasteAction() { + return false; + } + + @Override + public boolean supportDeleteAction() { + return true; + } + }; + } + + @Override + public boolean accept(XCreator creator, int x, int y) { + return true; + } + + + @Override + public HoverPainter getPainter() { + return new FRFixLayoutPainter(container); + } + + @Override + public void dragStart(XCreator xCreator, SelectionModel selectionModel) { + //do nothing + } + + public void dragOver(XCreator xCreator, SelectionModel selectionModel, int x, int y) { + //当鼠标移出被拖拽的组件时,才将组件从selectionmodel 中移出 + if (xCreator.getBackupRectangle()!= null && !xCreator.getBackupRectangle().contains(x, y) + && selectionModel.getSelection().contains(xCreator.toData())) { + selectionModel.removeCreator(xCreator, xCreator.getWidth(), xCreator.getHeight()); + selectionModel.setSelectedCreator(container); + } + + } + + ; +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRNoFixLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRNoFixLayoutAdapter.java new file mode 100644 index 000000000..bdf67e00e --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRNoFixLayoutAdapter.java @@ -0,0 +1,116 @@ +package com.fr.design.designer.beans.adapters.layout; + +import com.fr.design.designer.beans.models.SelectionModel; +import com.fr.design.designer.beans.painters.AbstractPainter; +import com.fr.design.designer.beans.painters.FRFitLayoutPainter; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XWFitLayout; +import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; + +import java.awt.Component; +import java.util.ArrayList; + +public class FRNoFixLayoutAdapter extends AbstractLayoutAdapter { + private int minHeight; + private FRBodyLayoutAdapter parentLayoutAdapter; + + public FRNoFixLayoutAdapter(FRBodyLayoutAdapter parentLayoutAdapter, XLayoutContainer container, int minHeight) { + super(container); + this.parentLayoutAdapter = parentLayoutAdapter; + this.minHeight = minHeight; + } + + @Override + public void addComp(XCreator child, int x, int y) { + fix(child, x, y); + if (child.shouldScaleCreator() || child.hasTitleStyle()) { + addParentCreator(child); + } else { + container.add(child, child.toData().getWidgetName()); + } + XWFitLayout layout = (XWFitLayout) container; + // 更新对应的BoundsWidget + layout.updateBoundsWidget(); + updateCreatorBackBound(); + } + + private void updateCreatorBackBound() { + for (int i = 0, size = container.getComponentCount(); i < size; i++) { + XCreator creator = (XCreator) container.getComponent(i); + creator.updateChildBound(minHeight); + creator.setBackupBound(creator.getBounds()); + //tab布局用到 + ArrayList childrenList = creator.getTargetChildrenList(); + for (int j = 0; j < childrenList.size(); j++) { + XWTabFitLayout tabLayout = (XWTabFitLayout) childrenList.get(j); + for (int m = 0; m < tabLayout.getComponentCount(); m++) { + XCreator childCreator = tabLayout.getXCreator(m); + childCreator.setBackupBound(childCreator.getBounds()); + } + } + } + } + + private void addParentCreator(XCreator child) { + XLayoutContainer parentPanel = child.initCreatorWrapper(minHeight); + container.add(parentPanel, child.toData().getWidgetName()); + } + + private void fix(XCreator child, int x, int y) { + Component parentComp = container.getComponentAt(x, y); + if (container.getComponentCount() == 0) { + child.setLocation(0, 0); + child.setSize(parentComp.getWidth(), parentComp.getHeight()); + } else if (parentLayoutAdapter.isCrossPointArea(parentComp, x, y)) { + //交叉区域插入组件时,根据具体位置进行上下或者左右或者相邻三个组件的位置大小插入 + parentLayoutAdapter.fixCrossPointArea(parentComp, child, x, y); + return; + } else if (parentLayoutAdapter.isTrisectionArea(parentComp, x, y)) { + // 在边界三等分区域,就不再和组件二等分了 + parentLayoutAdapter.fixTrisect(parentComp, child, x, y); + return; + } else { + parentLayoutAdapter.fixHalve(parentComp, child, x, y); + } + } + + @Override + public void delete(XCreator creator, int creatorWidth, int creatorHeight) { + int x = creator.getX(); + int y = creator.getY(); + ((FRFitLayoutAdapter)parentLayoutAdapter).recalculateChildrenSize(x, y, creatorWidth, creatorHeight, true); + } + + + @Override + public boolean supportModifyInsert() { + return true; + } + + @Override + public DesignerBaseOperate getDesignerBaseOperate() { + return new DefaultDesignerBaseOperate() { + @Override + public boolean supportCutAction() { + return container.getComponentCount() > 1; + } + }; + } + + @Override + public boolean accept(XCreator creator, int x, int y) { + return true; + } + + @Override + public AbstractPainter getPainter() { + return new FRFitLayoutPainter(container); + } + + @Override + public void dragStart(XCreator xCreator, SelectionModel selectionModel) { + selectionModel.removeCreator(xCreator, xCreator.getWidth(), xCreator.getHeight()); + selectionModel.setSelectedCreator(container); + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FROccupiedLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FROccupiedLayoutAdapter.java new file mode 100644 index 000000000..00dc41aed --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FROccupiedLayoutAdapter.java @@ -0,0 +1,63 @@ +package com.fr.design.designer.beans.adapters.layout; + +import com.fr.design.designer.beans.HoverPainter; +import com.fr.design.designer.beans.painters.FROccupiedLayoutPainter; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.treeview.DefaultXCreatorTreeCellRender; +import com.fr.design.designer.treeview.XCreatorTreeCellRender; +import com.fr.design.utils.gui.LayoutUtils; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; + +public class FROccupiedLayoutAdapter extends AbstractLayoutAdapter { + + public FROccupiedLayoutAdapter(XLayoutContainer container) { + super(container); + painter = new FROccupiedLayoutPainter(container); + } + + private HoverPainter painter; + + + @Override + protected void addComp(XCreator creator, int x, int y) { + if (container.getComponentCount() == 0) { + creator.setLocation(container.getLocation().x, container.getLocation().y); + creator.setSize(container.getWidth(), container.getHeight()); + XLayoutContainer parent = (XLayoutContainer) container.getParent(); + if (creator.shouldScaleCreator() || creator.hasTitleStyle()) { + XLayoutContainer parentPanel = creator.initCreatorWrapper(21); + parent.replaceXcreator(parentPanel, container); + } else { + parent.replaceXcreator(creator, container); + } + LayoutUtils.layoutContainer(parent); + } + } + + @Override + public HoverPainter getPainter() { + return painter; + } + + @Override + public boolean accept(XCreator creator, int x, int y) { + return container.getComponentCount() == 0; + } + + public XCreatorTreeCellRender getLayoutTreeCellRender(XCreator creator) { + return new DefaultXCreatorTreeCellRender(creator) { + @Override + public void paint(Graphics g, Component c) { + super.paint(g, c); + Color oldColor = g.getColor(); + g.setColor(Color.RED); + g.drawRect(0, 0, 16, 16); + g.setColor(oldColor); + } + }; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/events/DesignerEditor.java b/designer-form/src/main/java/com/fr/design/designer/beans/events/DesignerEditor.java index 58f58c075..e023e1f4d 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/events/DesignerEditor.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/events/DesignerEditor.java @@ -77,12 +77,12 @@ public class DesignerEditor implements PropertyChangeListe } } - public void paintEditor(Graphics g, Dimension size, PaddingMargin margin) { + public void paintEditor(Graphics g, Dimension size, Insets margin) { if (this.comp != null) { - int marginLeft = margin != null ? margin.getLeft() : 0; - int marginTop = margin != null ? margin.getTop() : 0; - int marginRight = margin != null ? margin.getRight() : 0; - int marginBottom = margin != null ? margin.getBottom() : 0; + int marginLeft = margin.left; + int marginTop = margin.top; + int marginRight = margin.right; + int marginBottom = margin.bottom; int horizonMargin = marginLeft + marginRight; int verticalMargin = marginTop + marginBottom; diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/AddingModel.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/AddingModel.java index c0b6cd400..1926b57b1 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/models/AddingModel.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/AddingModel.java @@ -4,8 +4,8 @@ import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.adapters.component.CompositeComponentAdapter; import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XLayoutContainer; -import com.fr.design.designer.creator.XWAbsoluteLayout; import com.fr.design.designer.creator.XWParameterLayout; import com.fr.design.mainframe.FormDesigner; import com.fr.design.utils.ComponentUtils; @@ -51,9 +51,8 @@ public class AddingModel { this.creator = xCreator; this.creator.backupCurrentSize(); this.creator.backupParent(); - this.creator.setSize(xCreator.initEditorSize()); - currentX = x - (xCreator.getWidth() / 2); - currentY = y - (xCreator.getHeight() / 2); + currentX = x - (xCreator.initEditorSize().width / 2); + currentY = y - (xCreator.initEditorSize().height / 2); } /** @@ -93,8 +92,8 @@ public class AddingModel { * @param y 坐标 */ public void moveTo(int x, int y) { - currentX = x - (this.creator.getWidth() / 2); - currentY = y - (this.creator.getHeight() / 2); + currentX = x - (this.creator.initEditorSize().width / 2); + currentY = y - (this.creator.initEditorSize().height / 2); } public XCreator getXCreator() { @@ -125,11 +124,10 @@ public class AddingModel { */ public boolean add2Container(FormDesigner designer, XLayoutContainer container, int x, int y) { //考虑不同布局嵌套的情况,获取顶层容器 - XLayoutContainer xLayoutContainer = container.getTopLayout(); - if (xLayoutContainer != null && xLayoutContainer.acceptType(XWAbsoluteLayout.class)) { + XLayoutContainer xLayoutContainer = XCreatorUtils.getTopEditableContainer(container); + if (xLayoutContainer != null) { container = xLayoutContainer; } - Rectangle rect = ComponentUtils.getRelativeBounds(container); if (!ComparatorUtils.equals(container.getOuterLayout(), container.getBackupParent())) { added = container.getLayoutAdapter().addBean(creator, @@ -142,4 +140,5 @@ public class AddingModel { y + designer.getVerticalScaleValue() - rect.y); return added; } + } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java index 0f75896e1..dda70b96f 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java @@ -18,7 +18,7 @@ import java.util.Set; /** * created by Harrison on 2020/06/05 **/ -abstract class ModelUtil { +public abstract class ModelUtil { public static void renameWidgetName(Form form, XCreator xCreator) { diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/NewFormModel.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/NewFormModel.java new file mode 100644 index 000000000..141f6b1f3 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/NewFormModel.java @@ -0,0 +1,68 @@ +package com.fr.design.designer.beans.models; + +import com.fr.design.designer.beans.PredefinedLayout; +import com.fr.design.i18n.Toolkit; +import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; +import com.fr.third.fasterxml.jackson.databind.ObjectMapper; + +import java.io.InputStream; +import java.io.Serializable; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class NewFormModel implements Serializable { + private static final String CONFIG_FILE_PATH = "/com/fr/design/form/layouts/config.json"; + private static NewFormModel holder = null; + private Map> config = new LinkedHashMap<>(); + + private final Map i18nMap = new HashMap() {{ + put("2-4", Toolkit.i18nText("Fine-Design_Layout_Two_To_Four_Module")); + put("5-7", Toolkit.i18nText("Fine-Design_Layout_Five_To_Seven_Module")); + put("multi", Toolkit.i18nText("Fine-Design_Layout_Multi_Module")); + }}; + + public static NewFormModel getInstance() { + if (holder == null) { + try { + holder = new ObjectMapper().readValue(readConfigFile(), NewFormModel.class); + } catch (Exception e) { + holder = new NewFormModel(); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + return holder; + } + + private NewFormModel() { + + } + + private synchronized static String readConfigFile() { + String result = StringUtils.EMPTY; + InputStream is = null; + try { + is = IOUtils.readResource(CONFIG_FILE_PATH); + result = IOUtils.inputStream2String(is); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + IOUtils.close(is); + } + return result; + } + + public Map> getConfig() { + return config; + } + + public void setConfig(Map> config) { + for (String key : config.keySet()) { + String i18nKey = StringUtils.isNotEmpty(i18nMap.get(key)) ? i18nMap.get(key) : key; + this.config.put(i18nKey, config.get(key)); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java index df645e2df..963f60e6c 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java @@ -140,11 +140,28 @@ public class SelectionModel { if (cutSelection != null) { cutSelection.cut2ClipBoard(clipboard); designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_CUTED); + setSelectedCreator(hasSelectedParaComponent() ? designer.getParaComponent() : designer.getRootComponent()); designer.repaint(); } } } + /** + * 判断是否选中参数面板中的组件 + * @return boolean + */ + private boolean hasSelectedParaComponent() { + XCreator[] roots = selection.getSelectedCreators(); + if (roots.length > 0) { + for (XCreator creator : roots) { + if ((creator.getParent() instanceof XWParameterLayout)) { + return true; + } + } + } + return false; + } + /** * 复制当前选中的组件到剪切板 */ @@ -320,8 +337,7 @@ public class SelectionModel { } designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_DELETED); - setSelectedCreator(isInPara ? designer.getParaComponent() : designer.getRootComponent()); - + setSelectedCreator(isInPara? designer.getParaComponent() : designer.getRootComponent()); // 触发事件 designer.repaint(); diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/painters/FRFixLayoutPainter.java b/designer-form/src/main/java/com/fr/design/designer/beans/painters/FRFixLayoutPainter.java new file mode 100644 index 000000000..f450a437a --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/painters/FRFixLayoutPainter.java @@ -0,0 +1,130 @@ +package com.fr.design.designer.beans.painters; + +import com.fr.design.designer.beans.painters.AbstractPainter; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XOccupiedLayout; +import com.fr.design.form.util.XCreatorConstants; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Component; +import java.awt.Composite; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Stroke; + +public class FRFixLayoutPainter extends AbstractPainter { + + /** + * 构造函数 + * + * @param container + */ + public FRFixLayoutPainter(XLayoutContainer container) { + super(container); + } + + /** + * 组件渲染 + * + * @param g 画图类 + * @param startX 开始位置x + * @param startY 开始位置y + */ + @Override + public void paint(Graphics g, int startX, int startY) { + super.paint(g, startX, startY); + int x = hotspot.x - hotspot_bounds.x; + int y = hotspot.y - hotspot_bounds.y; + Component currentComp = container.getComponentAt(x, y); + if (currentComp == null) { + return; + } + boolean accept = currentComp != container; + if (accept) { + OperateState state = OperateState.DEFAULT; + if (currentComp == creator) { + state = OperateState.COMPONENT_DRAG_OUT; + } else if (!((XCreator) currentComp).acceptType(XOccupiedLayout.class)) { + state = OperateState.COMPONENT_REPLACE; + } + state.paint(g, creator.getBackupRectangle(), currentComp.getBounds(), new Rectangle(x, y, creator.initEditorSize().width, ((XCreator) currentComp).initEditorSize().height)); + } else { + Color bColor = XCreatorConstants.LAYOUT_FORBIDDEN_COLOR; + int[] hot_rec = new int[]{x, y, 0, 0}; + drawHotspot(g, x, y, hot_rec[2], hot_rec[3], bColor, false, false); + } + + } + + + enum OperateState { + COMPONENT_REPLACE { + @Override + void paint(Graphics g, Rectangle oriRectangle, Rectangle currentRectangle, Rectangle hotspot_bounds) { + Graphics2D g2d = (Graphics2D) g; + Color color = g2d.getColor(); + Stroke backup = g2d.getStroke(); + Composite backupComp = g2d.getComposite(); + + g2d.setColor(XCreatorConstants.REPLACE_OCCUPIED_LAYOUT_COLOR); + g2d.setStroke(XCreatorConstants.DASH_STROKE); + //绘制当前组件的边框 + g2d.drawRect(currentRectangle.x, currentRectangle.y, currentRectangle.width, currentRectangle.height); + //底色透明度0.2 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f)); + //绘制进行替换的时候,被替换的组件的底色 + g2d.fillRect(currentRectangle.x, currentRectangle.y, currentRectangle.width, currentRectangle.height); + + //绘制原组件位置处的占位块 + if (oriRectangle != null) { + g2d.setColor(XCreatorConstants.DRAG_OUT_OCCUPIED_LAYOUT_COLOR); + //如果是从其他占位块上拖过来的,绘制下其他占位块的状态 + g2d.drawRect(oriRectangle.x + 1, oriRectangle.y + 1, oriRectangle.width - 2, oriRectangle.height - 2); + //底色透明度0.2 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f)); + //绘制进行替换的时候,被替换的组件的底色 + g2d.fillRect(oriRectangle.x, oriRectangle.y, oriRectangle.width, oriRectangle.height); + } + //还原 + g2d.setComposite(backupComp); + g2d.setStroke(backup); + g2d.setColor(color); + } + }, + COMPONENT_DRAG_OUT { + @Override + void paint(Graphics g, Rectangle oriRectangle, Rectangle currentRectangle, Rectangle hotspot_bounds) { + Graphics2D g2d = (Graphics2D) g; + Color color = g2d.getColor(); + Stroke backup = g2d.getStroke(); + Composite backupComp = g2d.getComposite(); + // 设置线条的样式 + g2d.setStroke(XCreatorConstants.DASH_STROKE); + g2d.setColor(XCreatorConstants.DRAG_OUT_OCCUPIED_LAYOUT_COLOR); + //如果是从其他占位块上拖过来的,绘制下其他占位块的状态 + g2d.drawRect(oriRectangle.x, oriRectangle.y, oriRectangle.width, oriRectangle.height); + //底色透明度0.2 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f)); + //绘制进行替换的时候,被替换的组件的底色 + g2d.fillRect(oriRectangle.x, oriRectangle.y, oriRectangle.width, oriRectangle.height); + + g2d.setComposite(backupComp); + g2d.setStroke(backup); + g2d.setColor(color); + } + }, + DEFAULT { + @Override + void paint(Graphics g, Rectangle oriRectangle, Rectangle currentRectangle, Rectangle hotspot_bounds) { + + } + }; + + abstract void paint(Graphics g, Rectangle oriRectangle, Rectangle currentRectangle, Rectangle hotspot_bounds); + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/painters/FROccupiedLayoutPainter.java b/designer-form/src/main/java/com/fr/design/designer/beans/painters/FROccupiedLayoutPainter.java new file mode 100644 index 000000000..33a809a89 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/painters/FROccupiedLayoutPainter.java @@ -0,0 +1,56 @@ +package com.fr.design.designer.beans.painters; + +import com.fr.design.designer.beans.adapters.layout.FROccupiedLayoutAdapter; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.form.util.XCreatorConstants; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Component; +import java.awt.Composite; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Stroke; + +public class FROccupiedLayoutPainter extends AbstractPainter { + + /** + * 构造函数 + * + * @param container 容器 + */ + public FROccupiedLayoutPainter(XLayoutContainer container) { + super(container); + } + + @Override + public void paint(Graphics g, int startX, int startY) { + int x = hotspot.x - hotspot_bounds.x; + int y = hotspot.y - hotspot_bounds.y; + FROccupiedLayoutAdapter adapter = (FROccupiedLayoutAdapter) container.getLayoutAdapter(); + Component currentComp = container.getComponentAt(x, y); + if (currentComp == null) { + return; + } + boolean accept = adapter.accept(creator, x, y); + if (accept) { + Color backupColor = g.getColor(); + Graphics2D g2d = (Graphics2D) g; + Stroke backupStroke = g2d.getStroke(); + Composite backupComposite = g2d.getComposite(); + g2d.setColor(XCreatorConstants.DRAG_IN_OCCUPIED_LAYOUT_COLOR); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.05f)); + g2d.fillRect(container.getX(), container.getY(), container.getWidth(), container.getHeight()); + + g2d.setStroke(XCreatorConstants.DASH_STROKE); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f)); + g2d.drawRect(container.getX() + 1, container.getY() + 1, container.getWidth() - 2, container.getHeight() - 2); + g2d.setStroke(backupStroke); + g2d.setComposite(backupComposite); + g2d.setColor(backupColor); + } + + } + + +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java index 0ff99f3a9..60434f2cb 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java @@ -40,6 +40,7 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ protected double backgroundOpacity4Painting; // 设计器预览界面中绘制组件背景图 protected Background borderImage4Painting; // 设计器预览界面中绘制边框图片 protected double borderImageOpacity4Painting; + protected Insets paddingInsets4Painting; public XBorderStyleWidgetCreator(Widget widget, Dimension initSize) { super(widget, initSize); @@ -87,6 +88,24 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ this.borderImageOpacity4Painting = opacity; } + public void setPaddingInsets4Painting(PaddingMargin margin) { + if (this.paddingInsets4Painting == null) { + this.paddingInsets4Painting = new Insets(0, 0, 0, 0); + } + if (margin == null) { + this.paddingInsets4Painting.set(0, 0, 0, 0); + } else { + this.paddingInsets4Painting.set(margin.getTop(), margin.getLeft(), margin.getBottom(), margin.getRight()); + } + } + + protected Insets getPaddingInsets4Painting() { + if (this.paddingInsets4Painting == null) { + this.paddingInsets4Painting = new Insets(0, 0, 0, 0); + } + return this.paddingInsets4Painting; + } + /** * 返回容器对应的widget * @return 同上 @@ -371,11 +390,13 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ */ @Override public Insets getInsets() { - PaddingMargin padding = toData().getMargin(); - if (padding == null) { - return new Insets(0, 0, 0, 0); - } - return new Insets(padding.getTop(), padding.getLeft(), padding.getBottom(), padding.getRight()); + Container parent = this.getParent(); + if (parent instanceof XWTitleLayout && parent.getComponentCount() > 1) { + setPaddingInsets4Painting(null); + } else { + setPaddingInsets4Painting(toData().getMargin()); + } + return getPaddingInsets4Painting(); } /** diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java b/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java index ee166d27e..1ab6d1a31 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java @@ -230,7 +230,7 @@ public class XChartEditor extends XBorderStyleWidgetCreator { @Override public void paintForeground(Graphics2D g) { Dimension size = getSize(); - PaddingMargin margin = toData().getMargin(); + Insets paddingInsets = getInsets(); if (!isEditing) { // CHART-20568 & CHART-20627 @@ -238,12 +238,12 @@ public class XChartEditor extends XBorderStyleWidgetCreator { // 同时这里又在下层绘制了一遍ChartComponent,导致图表进入编辑状态,会出现两个重叠的ChartComponent。 // 考虑到编辑中,FormDesigner中的ChartComponent位于上层,下层的ChartComponent实际上没什么用,所以可以不用绘制 // 下层的ChartComponent - designerEditor.paintEditor(g, size, margin); + designerEditor.paintEditor(g, size, paddingInsets); } if (coverPanel != null) { - int horizonMargin = margin != null ? margin.getLeft() + margin.getRight() : 0; - int verticalMargin = margin != null ? margin.getTop() + margin.getBottom() : 0; + int horizonMargin = paddingInsets.left + paddingInsets.right; + int verticalMargin = paddingInsets.top + paddingInsets.bottom; coverPanel.setSize(size.width - horizonMargin, size.height - verticalMargin); } super.paintForeground(g); @@ -274,23 +274,24 @@ public class XChartEditor extends XBorderStyleWidgetCreator { return; } FormDesigner designer = editingMouseListener.getDesigner(); - SelectionModel selectionModel = editingMouseListener.getSelectionModel(); isEditing = e.getButton() == MouseEvent.BUTTON1 && (e.getClickCount() == 2 || designer.getCursor().getType() == Cursor.HAND_CURSOR); - displayCoverPane(!isEditing); - selectionModel.selectACreatorAtMouseEvent(e); - editingMouseListener.refreshTopXCreator(isEditing); + startEditing(editingMouseListener, designer, isEditing); + } + @Override + protected void startEditing(EditingMouseListener editingMouseListener, FormDesigner designer, boolean editing) { + displayCoverPane(!editing); + SelectionModel selectionModel = editingMouseListener.getSelectionModel(); + selectionModel.reset(); + selectionModel.selectACreator(this); + editingMouseListener.refreshTopXCreator(editing); if (editingMouseListener.stopEditing()) { - if (this != (XCreator) designer.getRootComponent()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - if (isEditing) { - EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_SETTINGS); - } - editingMouseListener.startEditing(this, isEditing ? adapter.getDesignerEditor() : null, adapter); - if (isEditing) { - EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_SETTINGS); - } + isEditing = editing; + ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); + editingMouseListener.startEditing(this, isEditing ? adapter.getDesignerEditor() : null, adapter); + if (editing) { + EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_SETTINGS); } } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java index 87a1926cb..4601c268a 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java @@ -7,10 +7,12 @@ import com.fr.base.GraphHelper; import com.fr.base.vcs.DesignerMode; import com.fr.design.ExtraDesignClassManager; import com.fr.design.actions.UpdateAction; -import com.fr.design.designer.beans.AdapterBus; -import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.events.DesignerEditor; import com.fr.design.designer.beans.models.SelectionModel; +import com.fr.design.designer.creator.operate.XCreatorBaseOperate; +import com.fr.design.designer.creator.operate.DefaultXCreatorBaseOperate; +import com.fr.design.designer.treeview.DefaultXCreatorTreeCellRender; +import com.fr.design.designer.treeview.XCreatorTreeCellRender; import com.fr.design.designer.ui.SelectedPopupDialog; import com.fr.design.fun.ShareWidgetUIProcessor; import com.fr.design.fun.WidgetPropertyUIProvider; @@ -28,10 +30,12 @@ import com.fr.design.plugin.DesignerPluginContext; import com.fr.design.utils.gui.LayoutUtils; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WTitleLayout; +import com.fr.stable.ArrayUtils; import com.fr.stable.Constants; import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; +import java.awt.event.MouseListener; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JFrame; @@ -62,7 +66,7 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo protected static final Dimension MIDDLE_PREFERRED_SIZE = new Dimension(80, 50); protected static final Dimension BIG_PREFERRED_SIZE = new Dimension(80, 80); // barry: 拖拽控件时,控件要恢复原始大小,就先把控件当前大小备份到这里。 - protected Dimension backupSize; + protected Rectangle backupRectangle; protected XLayoutContainer backupParent; protected Widget data; @@ -107,11 +111,15 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo * 应用备份的大小 */ public void useBackupSize() { - if (this.backupSize != null) { - setSize(this.backupSize); + if (this.backupRectangle != null) { + setSize(new Dimension(this.backupRectangle.width, this.backupRectangle.height)); } } + public Rectangle getBackupRectangle(){ + return this.backupRectangle; + } + /** * 初始化组件大小 */ @@ -128,7 +136,7 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo * 备份当前大小 */ public void backupCurrentSize() { - this.backupSize = getSize(); + this.backupRectangle = getBounds(); } public XLayoutContainer getBackupParent() { @@ -546,21 +554,31 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo * @param e 鼠标点击事件 */ public void respondClick(EditingMouseListener editingMouseListener,MouseEvent e){ - FormDesigner designer = editingMouseListener.getDesigner(); SelectionModel selectionModel = editingMouseListener.getSelectionModel(); if (e.getClickCount() <= 1) { selectionModel.selectACreatorAtMouseEvent(e); } - editingMouseListener.refreshTopXCreator(); + } - if (editingMouseListener.stopEditing() && this != designer.getRootComponent()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter); + /** + * + * 进入编辑模式 + */ + public void startEditing() { + FormDesigner designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + MouseListener[] listeners = designer.getMouseListeners(); + if (ArrayUtils.isNotEmpty(listeners) && listeners[0] instanceof EditingMouseListener) { + startEditing(((EditingMouseListener) listeners[0]), designer, true); } } + protected void startEditing(EditingMouseListener editingMouseListener, FormDesigner designer, boolean editing) { + // do nothing + // 子类按需实现 + } + /** * 删除相关组件 * @@ -894,4 +912,24 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo } return ((XCreator) this.getParent()).getLevel() + 1; } + + /** + * 获取组件在组件树中的显示方式 + * @return + */ + public XCreatorTreeCellRender getComponentTreeCellRender(){ + if (this.getBackupParent()!= null){ + return this.getBackupParent().getLayoutAdapter().getLayoutTreeCellRender(this); + } + return new DefaultXCreatorTreeCellRender(this); + } + + /** + * 获取组件支持的基本操作 + * @return + */ + public XCreatorBaseOperate getXCreatorBaseOperate() { + return new DefaultXCreatorBaseOperate(); + } + } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java index b7fd34df9..408723152 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java @@ -55,6 +55,7 @@ import com.fr.form.ui.TreeComboBoxEditor; import com.fr.form.ui.TreeEditor; import com.fr.form.ui.Widget; import com.fr.form.ui.WidgetErrorMarker; +import com.fr.form.ui.container.OccupiedLayout; import com.fr.form.ui.container.WAbsoluteBodyLayout; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WBorderLayout; @@ -138,6 +139,7 @@ public class XCreatorUtils { xLayoutMap.put(WBorderLayout.class, XWBorderLayout.class); xLayoutMap.put(WCardLayout.class, XWCardLayout.class); xLayoutMap.put(WVerticalBoxLayout.class, XWVerticalBoxLayout.class); + xLayoutMap.put(OccupiedLayout.class, XOccupiedLayout.class); xLayoutMap.put(WFitLayout.class, XWFitLayout.class); xLayoutMap.put(WScaleLayout.class, XWScaleLayout.class); @@ -273,7 +275,7 @@ public class XCreatorUtils { try { creator = Reflect.on(clazz).create(widget, d).get(); } catch (Exception ignore) { - + FineLoggerFactory.getLogger().error(ignore.getMessage(), ignore); } if (creator == null) { FineLoggerFactory.getLogger().error("Error to create xcreator!"); @@ -400,4 +402,22 @@ public class XCreatorUtils { FineColorFlushUtils.replaceCacheObject(container.toData(), colorGather); FineColorManager.traverse(container.toData(), colorGather); } + + + /** + * 获取容器组件的顶层正编辑的组件 + */ + @Nullable + public static XLayoutContainer getTopEditableContainer(XLayoutContainer container) { + if (container == null) { + return null; + } + XLayoutContainer xLayoutContainer = container.getTopLayout(); + if (xLayoutContainer != null && xLayoutContainer.getParent() != null) { + if (!xLayoutContainer.isEditable()) { + return (XLayoutContainer) xLayoutContainer.getParent(); + } + } + return null; + } } \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java index cf8b7a766..42a14aee3 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java @@ -50,8 +50,7 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme public XElementCase(ElementCaseEditor widget, Dimension initSize) { super(widget, initSize); - - + widget.getElementCaseImage().adjustImageSize(initSize.width, initSize.height, false); } protected void initXCreatorProperties() { @@ -325,11 +324,13 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme private void switchTab(MouseEvent e, EditingMouseListener editingMouseListener) { FormDesigner designer = editingMouseListener.getDesigner(); - if (e.getButton() == MouseEvent.BUTTON1 && - (e.getClickCount() == 2 || designer.getCursor().getType() == Cursor.HAND_CURSOR)) { - //切换设计器 - designer.switchTab(this); - } + startEditing(editingMouseListener, designer, e.getButton() == MouseEvent.BUTTON1 && + (e.getClickCount() == 2 || designer.getCursor().getType() == Cursor.HAND_CURSOR)); + } + + @Override + protected void startEditing(EditingMouseListener editingMouseListener, FormDesigner designer, boolean editing) { + designer.switchTab(this); } @Override diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java b/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java index f1d4c4f6d..801f18969 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java @@ -4,9 +4,11 @@ package com.fr.design.designer.creator; import com.fr.design.designer.beans.LayoutAdapter; +import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.form.layout.FRLayoutManager; import com.fr.design.form.util.XCreatorConstants; import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.EditingMouseListener; import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.widget.editors.PaddingMarginEditor; import com.fr.design.mainframe.widget.editors.WLayoutBorderStyleEditor; @@ -50,6 +52,8 @@ public abstract class XLayoutContainer extends XBorderStyleWidgetCreator impleme private volatile boolean dragInAble; + protected boolean isFixLayout = false; + public void setMouseEnter(boolean mouseEnter) { isMouseEnter = mouseEnter; } @@ -59,6 +63,10 @@ public abstract class XLayoutContainer extends XBorderStyleWidgetCreator impleme this.addContainerListener(this); } + public void setFixLayout(boolean isFixLayout){ + this.isFixLayout = isFixLayout; + } + /** * 得到属性名 * @@ -586,4 +594,22 @@ public abstract class XLayoutContainer extends XBorderStyleWidgetCreator impleme public void setDragInAble(boolean dragInAble) { this.dragInAble = dragInAble; } + + @Override + protected void startEditing(EditingMouseListener editingMouseListener, FormDesigner designer, boolean editing) { + SelectionModel selectionModel = editingMouseListener.getSelectionModel(); + selectionModel.reset(); + selectionModel.selectACreator(this); + setEditable(editing); + editingMouseListener.refreshTopXCreator(editing); + designer.repaint(); + } + + public boolean supportFixLayout(){ + return false; + } + + public void replaceXcreator(XCreator newCreator, XCreator oldCreator){ + + } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XOccupiedLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XOccupiedLayout.java new file mode 100644 index 000000000..561a9437c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XOccupiedLayout.java @@ -0,0 +1,81 @@ +package com.fr.design.designer.creator; + +import com.fr.design.designer.beans.LayoutAdapter; +import com.fr.design.designer.beans.adapters.layout.FROccupiedLayoutAdapter; +import com.fr.design.designer.creator.operate.DefaultXCreatorBaseOperate; +import com.fr.design.designer.creator.operate.XCreatorBaseOperate; +import com.fr.design.form.layout.FRFitLayout; +import com.fr.design.form.util.XCreatorConstants; +import com.fr.form.ui.container.OccupiedLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Stroke; + +public class XOccupiedLayout extends XLayoutContainer { + + public XOccupiedLayout() { + this(new OccupiedLayout(), new Dimension()); + } + + + public XOccupiedLayout(OccupiedLayout widget, Dimension initSize) { + super(widget, initSize); + initLayoutManager(); + } + + public String createDefaultName() { + return "box"; + } + + @Override + protected void initLayoutManager() { + this.setLayout(new FRFitLayout()); + } + + @Override + public LayoutAdapter getLayoutAdapter() { + return new FROccupiedLayoutAdapter(this); + } + + + public String getIconPath() { + return "/com/fr/design/form/images/occupied_layout.png"; + } + + + @Override + public boolean isComponentTreeLeaf() { + //在控件树上表现为叶子节点(组件放置到占位块中的时候,会删除占位块,只展示组件) + return true; + } + + public XCreatorBaseOperate getXCreatorBaseOperate() { + return new DefaultXCreatorBaseOperate() { + @Override + public boolean supportSelected() { + return false; + } + }; + } + + + @Override + public void paint(Graphics g) { + drawOccupiedComponentBounds(g); + } + + private void drawOccupiedComponentBounds(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + Color color = g2d.getColor(); + Stroke backup = g2d.getStroke(); + // 设置线条的样式 + g2d.setStroke(XCreatorConstants.DASH_STROKE); + g2d.setColor(XCreatorConstants.EMPTY_OCCUPIED_LAYOUT_COLOR); + g2d.drawRect(1, 1, this.getWidth() - 2, this.getHeight() - 2); + g2d.setStroke(backup); + g2d.setColor(color); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java index e222b4486..f249a651e 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java @@ -490,21 +490,9 @@ public class XWAbsoluteLayout extends XLayoutContainer { return; } FormDesigner designer = editingMouseListener.getDesigner(); - SelectionModel selectionModel = editingMouseListener.getSelectionModel(); boolean isEditing = isEditable() || e.getButton() == MouseEvent.BUTTON1 && (designer.getCursor().getType() == Cursor.HAND_CURSOR || e.getClickCount() == 2); - setEditable(isEditing); - - selectionModel.selectACreatorAtMouseEvent(e); - designer.repaint(); - editingMouseListener.refreshTopXCreator(isEditing); - - if (editingMouseListener.stopEditing()) { - if (this != designer.getRootComponent()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, isEditing ? adapter.getDesignerEditor() : null, adapter); - } - } + startEditing(editingMouseListener, designer, isEditing); } /** diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java index 191add9b8..71aa6f990 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java @@ -2,6 +2,8 @@ package com.fr.design.designer.creator; import com.fr.design.designer.beans.LayoutAdapter; import com.fr.design.designer.beans.adapters.layout.FRFitLayoutAdapter; +import com.fr.design.designer.beans.adapters.layout.FRFixLayoutAdapter; +import com.fr.design.designer.beans.adapters.layout.FRNoFixLayoutAdapter; import com.fr.design.designer.beans.location.Direction; import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; @@ -80,7 +82,12 @@ public class XWFitLayout extends XLayoutContainer { @Override public LayoutAdapter getLayoutAdapter() { - return new FRFitLayoutAdapter(this); + FRFitLayoutAdapter layoutAdapter = new FRFitLayoutAdapter(this); + + if (isFixLayout) { + layoutAdapter.setFrLayoutState(new FRFixLayoutAdapter(this)); + } + return layoutAdapter; } @Override @@ -789,7 +796,6 @@ public class XWFitLayout extends XLayoutContainer { layout.setContainerHeight(containerHeight); layout.setContainerWidth(containerWidth); addCompInterval(getAcualInterval()); - // REPORT-54410: 决策报表,模板中其他组件的宽高修改会影响绝对画布块中组件的宽高和位置 // 绝对布局内的组件尺寸调整需要在绝对布局的bound排除GAP后进行,否则计算出的 // 组件尺寸缩放比例会有问题 @@ -867,7 +873,26 @@ public class XWFitLayout extends XLayoutContainer { BoundsWidget bw = (BoundsWidget) wlayout.getBoundsWidget(wgt); wlayout.removeWidget(bw); updateBoundsWidget(); - ((FRFitLayoutAdapter)getLayoutAdapter()).updateCreatorBackBound(); + ((FRFitLayoutAdapter) getLayoutAdapter()).updateCreatorBackBound(); + } + + public void replaceXcreator(XCreator newCreator, XCreator oldCreator) { + WFitLayout wlayout = this.toData(); + Widget wgt = oldCreator.toData(); + BoundsWidget bw = (BoundsWidget) wlayout.getBoundsWidget(wgt); + wlayout.removeWidget(bw); + wlayout.addWidget(new BoundsWidget(newCreator.toData(), bw.getBounds())); + newCreator.setBackupParent(this); + isRefreshing = true; + this.remove(oldCreator); + this.add(newCreator); + //对于新增的绝对布局的组件,需要更新下内部组件的大小 + if (newCreator.acceptType(XWAbsoluteLayout.class)){ + ((XWAbsoluteLayout) newCreator).updateBoundsWidget(); + newCreator.setBackupBound(newCreator.getBounds()); + } + isRefreshing = false; + LayoutUtils.layoutContainer(this); } /** @@ -1005,7 +1030,7 @@ public class XWFitLayout extends XLayoutContainer { * @return 默认返回true */ public boolean canAddInterval(int interval) { - int val = interval/2; + int val = (interval - this.toData().getCompInterval())/2; for (int i=0, len=this.getComponentCount(); i 1) { + XCreator bodyCreator = getBodyCreator(); + if (bodyCreator instanceof XBorderStyleWidgetCreator) { + XBorderStyleWidgetCreator styleBodyCreator = (XBorderStyleWidgetCreator) bodyCreator; + setPaddingInsets4Painting(styleBodyCreator.toData().getMargin()); + return getPaddingInsets4Painting(); + } + } + return super.getInsets(); + } + @Override protected void initXCreatorProperties() { super.initXCreatorProperties(); @@ -187,12 +200,15 @@ public class XWTitleLayout extends DedicateLayoutContainer { Composite oldComposite = g2d.getComposite(); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, (float) this.titleBackgroundOpacity4Painting)); XCreator titleCreator = getTitleCreator(); - int titleHeight = titleCreator != null ? titleCreator.getHeight() : 0; + if (titleCreator != null) { + int height = titleCreator.getHeight(); + Insets paddingInsets = getInsets(); - Shape shape = new Rectangle2D.Double(0, 0, getWidth(), titleHeight); - titleBackground4Painting.paint(g2d, shape); + Shape shape = new Rectangle2D.Double(0, 0, getWidth(), height + paddingInsets.top); + titleBackground4Painting.paint(g2d, shape); - g2d.setComposite(oldComposite); + g2d.setComposite(oldComposite); + } } } @@ -201,14 +217,18 @@ public class XWTitleLayout extends DedicateLayoutContainer { Composite oldComposite = g2d.getComposite(); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, (float) this.bodyBackgroundOpacity4Painting)); - XCreator titleCreator = getTitleCreator(); - int titleHeight = titleCreator != null ? titleCreator.getHeight() : 0; - // 兼容性考虑,组件样式背景不作用在标题范围内,只作用在控件整体,但同时不能遮挡作用于整体的边框图片 - // 所以考虑样式背景与边框图片都由XWTitleLayout绘制,但样式背景要向下偏移标题栏的高度 - Shape shape = new Rectangle2D.Double(0, titleHeight, getWidth(), getHeight() - titleHeight); - bodyBackground4Painting.paint(g2d, shape); + XCreator bodyCreator = getBodyCreator(); + + if (bodyCreator != null) { + int y = bodyCreator.getY(); + int height = bodyCreator.getHeight(); + Insets paddingInsets = getInsets(); - g2d.setComposite(oldComposite); + Shape shape = new Rectangle2D.Double(0, y, getWidth(), height + paddingInsets.bottom); + bodyBackground4Painting.paint(g2d, shape); + + g2d.setComposite(oldComposite); + } } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardAddButton.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardAddButton.java index 7718e266f..d774e3489 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardAddButton.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardAddButton.java @@ -1,8 +1,6 @@ package com.fr.design.designer.creator.cardlayout; import com.fr.base.BaseUtils; -import com.fr.design.designer.beans.AdapterBus; -import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XButton; import com.fr.design.designer.creator.XLayoutContainer; @@ -101,11 +99,6 @@ public class XCardAddButton extends XButton { addTab(index); this.tagLayout.adjustComponentWidth(); - if (editingMouseListener.stopEditing()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter); - } - FormHierarchyTreePane.getInstance().refreshRoot(); //将焦点切换到新增的tab对应的tabfitLayout上 showNewTab(editingMouseListener,index); diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java index 18bab5528..85436c72f 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java @@ -6,8 +6,6 @@ package com.fr.design.designer.creator.cardlayout; import com.fr.base.BaseUtils; import com.fr.base.GraphHelper; import com.fr.base.background.ColorBackground; -import com.fr.design.designer.beans.AdapterBus; -import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XButton; import com.fr.design.designer.creator.XCreator; @@ -32,7 +30,6 @@ import com.fr.general.ComparatorUtils; import com.fr.general.FRFont; import com.fr.general.act.TitlePacker; import com.fr.general.cardtag.TemplateStyle; -import com.fr.stable.ProductConstants; import com.fr.stable.unit.PT; import javax.swing.*; @@ -176,10 +173,6 @@ public class XCardSwitchButton extends XButton { tabFitLayout.setxCardSwitchButton(xCardSwitchButton); selectionModel.setSelectedCreator(tabFitLayout); - if (editingMouseListener.stopEditing()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter); - } if(SwingUtilities.isRightMouseButton(e)){ showPopupMenu(editingMouseListener, e, index, maxIndex); } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java index b784187e7..578b509ec 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java @@ -62,10 +62,6 @@ public class XWCardLayout extends XLayoutContainer { public static final String DEFAULT_NAME = "cardlayout"; - - //默认蓝色标题背景 - private static final Color TITLE_COLOR = new Color(51, 132, 240); - public XWCardLayout(WCardLayout widget, Dimension initSize) { super(widget, initSize); } @@ -399,19 +395,10 @@ public class XWCardLayout extends XLayoutContainer { @Override public void refreshStylePreviewEffect() { BorderPacker style = toData().getBorderStyle(); - initBorderTitleStyle(style); refreshBorderAndBackgroundStylePreviewEffect(); clearOrShowTitleLayout(ComparatorUtils.equals(style.getType(), LayoutBorderStyle.TITLE)); } - private void initBorderTitleStyle(BorderPacker style) { - //初始化默认标题样式 - style.setType(LayoutBorderStyle.TITLE); - style.setBorder(Constants.LINE_THIN); - TitlePacker widgetTitle = style.getTitle(); - widgetTitle.setBackground(ColorBackground.getInstance(TITLE_COLOR)); - } - //隐藏或显示标题部分 protected void clearOrShowTitleLayout(boolean isTitleStyle) { XWCardMainBorderLayout mainLayout = (XWCardMainBorderLayout) this.getBackupParent(); diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java index 0db348a39..fdc01be1e 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java @@ -377,21 +377,9 @@ public class XWCardMainBorderLayout extends XWBorderLayout { return; } FormDesigner designer = editingMouseListener.getDesigner(); - SelectionModel selectionModel = editingMouseListener.getSelectionModel(); boolean isEditing = e.getButton() == MouseEvent.BUTTON1 && (designer.getCursor().getType() == Cursor.HAND_CURSOR || e.getClickCount() == 2); - setEditable(isEditing); - - selectionModel.selectACreatorAtMouseEvent(e); - editingMouseListener.refreshTopXCreator(isEditing); - designer.repaint(); - - if (editingMouseListener.stopEditing()) { - if (this != designer.getRootComponent()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, isEditing ? adapter.getDesignerEditor() : null, adapter); - } - } + startEditing(editingMouseListener, designer, isEditing); } /** diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java index 010a38217..ceb334028 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java @@ -6,7 +6,6 @@ package com.fr.design.designer.creator.cardlayout; import com.fr.base.GraphHelper; import com.fr.base.ScreenResolution; import com.fr.design.designer.beans.AdapterBus; -import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.LayoutAdapter; import com.fr.design.designer.beans.adapters.layout.FRWCardTagLayoutAdapter; import com.fr.design.designer.beans.models.SelectionModel; @@ -242,19 +241,12 @@ public class XWCardTagLayout extends XWHorizontalBoxLayout { */ public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e) { - FormDesigner designer = editingMouseListener.getDesigner(); SelectionModel selectionModel = editingMouseListener.getSelectionModel(); if (e.getClickCount() <= 1) { selectionModel.selectACreatorAtMouseEvent(e); } editingMouseListener.refreshTopXCreator(); - if (editingMouseListener.stopEditing()) { - if (this != designer.getRootComponent()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter); - } - } } @Override diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTitleLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTitleLayout.java index f6f6b2b41..7cdca0a0b 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTitleLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTitleLayout.java @@ -3,8 +3,6 @@ */ package com.fr.design.designer.creator.cardlayout; -import com.fr.design.designer.beans.AdapterBus; -import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; @@ -198,20 +196,12 @@ public class XWCardTitleLayout extends XWBorderLayout { */ public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e) { - FormDesigner designer = editingMouseListener.getDesigner(); SelectionModel selectionModel = editingMouseListener.getSelectionModel(); if (e.getClickCount() <= 1) { selectionModel.selectACreatorAtMouseEvent(e); } editingMouseListener.refreshTopXCreator(); - - if (editingMouseListener.stopEditing()) { - if (this != designer.getRootComponent()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter); - } - } } @Override diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java index d72a8f4fe..10f080f69 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java @@ -639,4 +639,8 @@ public class XWTabFitLayout extends XWFitLayout { public boolean isTopable() { return true; } + + public boolean supportFixLayout(){ + return false; + } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/operate/DefaultXCreatorBaseOperate.java b/designer-form/src/main/java/com/fr/design/designer/creator/operate/DefaultXCreatorBaseOperate.java new file mode 100644 index 000000000..897b06ce4 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/creator/operate/DefaultXCreatorBaseOperate.java @@ -0,0 +1,29 @@ +package com.fr.design.designer.creator.operate; + + +public class DefaultXCreatorBaseOperate implements XCreatorBaseOperate { + @Override + public boolean supportSelected() { + return true; + } + + @Override + public boolean supportCopyAction() { + return true; + } + + @Override + public boolean supportCutAction() { + return true; + } + + @Override + public boolean supportPasteAction() { + return true; + } + + @Override + public boolean supportDeleteAction() { + return true; + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/operate/XCreatorBaseOperate.java b/designer-form/src/main/java/com/fr/design/designer/creator/operate/XCreatorBaseOperate.java new file mode 100644 index 000000000..3412501b3 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/creator/operate/XCreatorBaseOperate.java @@ -0,0 +1,15 @@ +package com.fr.design.designer.creator.operate; + +import com.fr.design.designer.beans.adapters.layout.DesignerBaseOperate; + +public interface XCreatorBaseOperate extends DesignerBaseOperate { + + /** + * 是否支持选中 + * + * @return boolean + */ + boolean supportSelected(); + + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java b/designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java index e3b9b8175..5aad58379 100644 --- a/designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java +++ b/designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java @@ -4,7 +4,6 @@ import com.fr.base.BaseUtils; import com.fr.design.constants.UIConstants; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; -import com.fr.design.mainframe.share.util.ShareComponentUtils; import com.fr.log.FineLoggerFactory; import javax.swing.BorderFactory; @@ -15,8 +14,7 @@ import java.awt.Component; import java.awt.Graphics; public class ComponentTreeCellRenderer extends DefaultTreeCellRenderer { - private boolean needAddShareIcon = false; - private static final Icon SHARE_ICON = BaseUtils.readIcon("/com/fr/design/images/toast/reuse_icon.png"); + private XCreatorTreeCellRender treeCellRender; public ComponentTreeCellRenderer() { } @@ -36,9 +34,8 @@ public class ComponentTreeCellRenderer extends DefaultTreeCellRenderer { } if (icon != null) { setIcon(icon); - this.needAddShareIcon = ShareComponentUtils.isShareWidgetWithChild((XCreator) value); } - + this.treeCellRender = ((XCreator) value).getComponentTreeCellRender(); } this.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0)); this.setBackgroundNonSelectionColor(UIConstants.TREE_BACKGROUND); @@ -48,9 +45,7 @@ public class ComponentTreeCellRenderer extends DefaultTreeCellRenderer { public void paint(Graphics g) { super.paint(g); - if (needAddShareIcon) { - SHARE_ICON.paintIcon(this, g, 10, 0); - } + treeCellRender.paint(g, this); } @Override diff --git a/designer-form/src/main/java/com/fr/design/designer/treeview/DefaultXCreatorTreeCellRender.java b/designer-form/src/main/java/com/fr/design/designer/treeview/DefaultXCreatorTreeCellRender.java new file mode 100644 index 000000000..702925e71 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/treeview/DefaultXCreatorTreeCellRender.java @@ -0,0 +1,29 @@ +package com.fr.design.designer.treeview; + +import com.fr.base.BaseUtils; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.mainframe.share.util.ShareComponentUtils; + +import javax.swing.Icon; +import java.awt.Component; +import java.awt.Graphics; + +public class DefaultXCreatorTreeCellRender implements XCreatorTreeCellRender { + private static final Icon SHARE_ICON = BaseUtils.readIcon("/com/fr/design/images/toast/reuse_icon.png"); + private XCreator xCreator; + + public DefaultXCreatorTreeCellRender(XCreator creator) { + this.xCreator = creator; + } + + public XCreator getxCreator(){ + return xCreator; + } + + @Override + public void paint(Graphics g, Component c) { + if (ShareComponentUtils.isShareWidgetWithChild( xCreator)) { + SHARE_ICON.paintIcon(c, g, 10, 0); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/treeview/XCreatorTreeCellRender.java b/designer-form/src/main/java/com/fr/design/designer/treeview/XCreatorTreeCellRender.java new file mode 100644 index 000000000..d919400be --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/treeview/XCreatorTreeCellRender.java @@ -0,0 +1,8 @@ +package com.fr.design.designer.treeview; + +import java.awt.Component; +import java.awt.Graphics; + +public interface XCreatorTreeCellRender { + void paint(Graphics g, Component c); +} diff --git a/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java b/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java index f806a72c0..e4da44c46 100644 --- a/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java +++ b/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java @@ -11,11 +11,9 @@ import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.VerticalFlowLayout; import com.fr.design.mainframe.CoverReportPane; -import com.fr.design.mainframe.EditingMouseListener; import com.fr.design.mainframe.FormDesigner; import com.fr.form.ui.Widget; import com.fr.general.IOUtils; -import com.fr.stable.ArrayUtils; import javax.swing.*; import java.awt.*; @@ -23,7 +21,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.List; @@ -72,13 +69,8 @@ public class PopupControlPanel extends JPanel { editButton.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - int x = rectangle.x + rectangle.width / 2; - int y = rectangle.y + rectangle.height / 2; XCreator childCreator = PopupControlPanel.this.creator.getEditingChildCreator(); - MouseListener[] listeners = designer.getMouseListeners(); - if (ArrayUtils.isNotEmpty(listeners) && listeners[0] instanceof EditingMouseListener) { - childCreator.respondClick(((EditingMouseListener) listeners[0]), new MouseEvent(childCreator, MouseEvent.MOUSE_CLICKED, e.getWhen(), e.getModifiers(), x, y, 2, false)); - } + childCreator.startEditing(); } }); return editButton; diff --git a/designer-form/src/main/java/com/fr/design/fit/NewJForm.java b/designer-form/src/main/java/com/fr/design/fit/NewJForm.java index 736e55bc6..6859c1231 100644 --- a/designer-form/src/main/java/com/fr/design/fit/NewJForm.java +++ b/designer-form/src/main/java/com/fr/design/fit/NewJForm.java @@ -52,6 +52,12 @@ public class NewJForm extends JForm { changePaneSize(); } + public NewJForm(Form form) { + super(form); + init(); + changePaneSize(); + } + public NewJForm(Form form, FILE file, Parameter[] parameters) { this(form, file); } diff --git a/designer-form/src/main/java/com/fr/design/fit/attrpane/ElementEditorExtendDefinePane.java b/designer-form/src/main/java/com/fr/design/fit/attrpane/ElementEditorExtendDefinePane.java deleted file mode 100644 index 20351165e..000000000 --- a/designer-form/src/main/java/com/fr/design/fit/attrpane/ElementEditorExtendDefinePane.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.fr.design.fit.attrpane; - -import com.fr.base.theme.FormTheme; -import com.fr.base.theme.TemplateTheme; -import com.fr.base.theme.settings.ThemedComponentStyle; -import com.fr.design.designer.IntervalConstants; -import com.fr.design.designer.creator.CRPropertyDescriptor; -import com.fr.design.designer.creator.PropertyGroupPane; -import com.fr.design.designer.creator.XCreator; -import com.fr.design.designer.creator.XElementCase; -import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.style.FollowingThemePane; -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.layout.TableLayoutHelper; -import com.fr.design.mainframe.widget.accessibles.AccessibleElementCaseToolBarEditor; -import com.fr.design.widget.ui.designer.component.PaddingBoundPane; -import com.fr.design.widget.ui.designer.layout.WTitleLayoutDefinePane; -import com.fr.form.main.Form; -import com.fr.form.ui.ElementCaseEditor; -import com.fr.form.ui.PaddingMargin; -import com.fr.form.web.FormToolBarManager; -import com.fr.general.ComparatorUtils; -import com.fr.report.fit.ReportFitAttr; - -import javax.swing.BorderFactory; -import javax.swing.JPanel; -import java.awt.BorderLayout; -import java.awt.Component; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by kerry on 2020-04-09 - */ -public class ElementEditorExtendDefinePane extends WTitleLayoutDefinePane { - private final PaddingBoundPane paddingBoundPane; - private AccessibleElementCaseToolBarEditor elementCaseToolBarEditor; - private PropertyGroupPane extraPropertyGroupPane; - private PcFitExpandablePane pcFitExpandablePane; - - private static final String FIT_STATE_PC = "fitStateInPC"; - - public ElementEditorExtendDefinePane(XCreator xCreator) { - super(xCreator); - paddingBoundPane = new PaddingBoundPane(); - themePane.addFollowThemePane(paddingBoundPane, new FollowingThemePane.FollowingThemeActionChangeListener() { - @Override - public void onFollowingTheme(boolean following) { - paddingBoundPane.setVisible(!following); - - if (following) { - TemplateTheme theme = themePane.getUsingTheme(); - if (theme instanceof FormTheme) { - ThemedComponentStyle style = ((FormTheme) theme).getComponentStyle(); - int top = style.getPaddingTop(); - int bottom = style.getPaddingBottom(); - int left = style.getPaddingLeft(); - int right = style.getPaddingRight(); - paddingBoundPane.populateBean(new PaddingMargin(top, left, bottom, right)); - } - } - } - }); - } - - protected JPanel createCenterPane() { - JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - elementCaseToolBarEditor = new AccessibleElementCaseToolBarEditor(); - Component[][] components = new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_EC_Toolbar")), elementCaseToolBarEditor}, - }; - JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_L1); - panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0)); - CRPropertyDescriptor[] extraTableEditor = removeOldFitEditor(((XElementCase) creator).getExtraTableEditor()); - extraPropertyGroupPane = new PropertyGroupPane(extraTableEditor, creator); - centerPane.add(panel, BorderLayout.NORTH); - if (extraTableEditor.length > 0) { - centerPane.add(extraPropertyGroupPane, BorderLayout.CENTER); - } - pcFitExpandablePane = new PcFitExpandablePane(this); - centerPane.add(pcFitExpandablePane, BorderLayout.SOUTH); - return centerPane; - } - - private CRPropertyDescriptor[] removeOldFitEditor(CRPropertyDescriptor[] extraTableEditor) { - List list = new ArrayList(); - for (CRPropertyDescriptor crPropertyDescriptor : extraTableEditor) { - if (!ComparatorUtils.equals(FIT_STATE_PC, crPropertyDescriptor.getName())) { - list.add(crPropertyDescriptor); - } - } - return list.toArray(new CRPropertyDescriptor[list.size()]); - } - - protected ElementCaseEditor updateSubBean() { - ElementCaseEditor elementCaseEditor = (ElementCaseEditor) creator.toData(); - if (themePane.isFollowingTheme() || ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate"))) { - paddingBoundPane.update(elementCaseEditor); - } - elementCaseEditor.setToolBars((FormToolBarManager[]) elementCaseToolBarEditor.getValue()); - ReportFitAttr fitAttr = pcFitExpandablePane.update(); - elementCaseEditor.setReportFitAttr(fitAttr); - return elementCaseEditor; - } - - - protected void populateSubBean(ElementCaseEditor ob) { - paddingBoundPane.populate(ob); - elementCaseToolBarEditor.setValue(ob.getToolBars()); - extraPropertyGroupPane.populate(ob); - pcFitExpandablePane.populate(ob.getReportFitAttr()); - - } -} diff --git a/designer-form/src/main/java/com/fr/design/fit/attrpane/FRAbsoluteBodyLayoutExtendDefinePane.java b/designer-form/src/main/java/com/fr/design/fit/attrpane/FRAbsoluteBodyLayoutExtendDefinePane.java deleted file mode 100644 index 563ed16aa..000000000 --- a/designer-form/src/main/java/com/fr/design/fit/attrpane/FRAbsoluteBodyLayoutExtendDefinePane.java +++ /dev/null @@ -1,198 +0,0 @@ -package com.fr.design.fit.attrpane; - -import com.fr.base.io.IOFile; -import com.fr.base.iofile.attr.WatermarkAttr; -import com.fr.base.theme.FormTheme; -import com.fr.base.theme.TemplateTheme; -import com.fr.design.data.DataCreatorUI; -import com.fr.design.designer.IntervalConstants; -import com.fr.design.designer.creator.XCreator; -import com.fr.design.designer.creator.XWFitLayout; -import com.fr.design.designer.properties.items.FRLayoutTypeItems; -import com.fr.design.designer.properties.items.Item; -import com.fr.design.foldablepane.UIExpandablePane; -import com.fr.design.gui.icombobox.UIComboBox; -import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.style.FollowingThemePane; -import com.fr.design.gui.xpane.LayoutStylePane; -import com.fr.design.i18n.Toolkit; -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.layout.TableLayout; -import com.fr.design.layout.TableLayoutHelper; -import com.fr.design.mainframe.WidgetPropertyPane; -import com.fr.design.mainframe.widget.accessibles.AccessibleBodyWatermarkEditor; -import com.fr.design.utils.gui.UIComponentUtils; -import com.fr.design.widget.FRWidgetFactory; -import com.fr.design.widget.ui.designer.component.WidgetBoundPane; -import com.fr.design.widget.ui.designer.layout.FRAbsoluteLayoutDefinePane; -import com.fr.form.ui.LayoutBorderStyle; -import com.fr.form.ui.container.WAbsoluteBodyLayout; -import com.fr.form.ui.container.WAbsoluteLayout; -import com.fr.form.ui.container.WBodyLayoutType; -import com.fr.general.act.BorderPacker; -import com.fr.report.core.ReportUtils; - -import javax.swing.BorderFactory; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JPanel; -import java.awt.BorderLayout; -import java.awt.Component; - -/** - * Created by kerry on 2020-04-22 - */ -public class FRAbsoluteBodyLayoutExtendDefinePane extends FRAbsoluteLayoutDefinePane { - private static final int MAX_LABEL_WIDTH = 80; - - protected FollowingThemePane themePane; - private LayoutStylePane stylePane; - private AccessibleBodyWatermarkEditor watermarkEditor; - - private UIComboBox layoutCombox; - private WBodyLayoutType layoutType = WBodyLayoutType.ABSOLUTE; - - public FRAbsoluteBodyLayoutExtendDefinePane(XCreator xCreator) { - super(xCreator); - } - - - public void initComponent() { - initUIComboBox(); - this.setLayout(FRGUIPaneFactory.createBorderLayout()); - - JPanel panel1 = FRGUIPaneFactory.createBorderLayout_S_Pane(); - this.add(panel1, BorderLayout.CENTER); - - UIExpandablePane scalePane = new UIExpandablePane( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Area_Scaling"), - 280, 20, - createAreaScalePane() - ); - panel1.add(scalePane, BorderLayout.NORTH); - - UIExpandablePane advancedPane = new UIExpandablePane( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), - 280, 20, - this.createAdvancePane()); - panel1.add(advancedPane, BorderLayout.CENTER); - - } - - public JPanel createAdvancePane() { - JPanel advancedContentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - - themePane = new FollowingThemePane(Toolkit.i18nText("Fine-Design_Form_Body_Style_Setting")); - stylePane = new LayoutStylePane(); - themePane.addFollowThemePane(stylePane, new FollowingThemePane.FollowingThemeActionChangeListener() { - @Override - public void onFollowingTheme(boolean following) { - stylePane.supportBodyStyle(!following); - - BorderPacker style = stylePane.updateBean(); - if (following) { - TemplateTheme theme = themePane.getUsingTheme(); - if (theme instanceof FormTheme) { - style = ((FormTheme) theme).getBodyStyle().merge(style); - } - } - stylePane.populateBean((LayoutBorderStyle) style); - } - }); - advancedContentPane.add(themePane, BorderLayout.NORTH); - - watermarkEditor = new AccessibleBodyWatermarkEditor(); - JPanel watermarkPane = TableLayoutHelper.createGapTableLayoutPane( - new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_WaterMark")), watermarkEditor} - }, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W3, IntervalConstants.INTERVAL_L1); - watermarkPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); - advancedContentPane.add(watermarkPane, BorderLayout.CENTER); - - return advancedContentPane; - } - - public JPanel createAreaScalePane() { - initLayoutComboBox(); - - UILabel layoutTypeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")); - - JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane( - new Component[][]{ - {layoutTypeLabel, layoutCombox} - }, - TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); - - contentPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); - - JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - containerPane.add(contentPane, BorderLayout.CENTER); - containerPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); - - return containerPane; - } - - public void initLayoutComboBox() { - Item[] items = FRLayoutTypeItems.ITEMS; - DefaultComboBoxModel model = new DefaultComboBoxModel(); - for (Item item : items) { - model.addElement(item); - } - layoutCombox = new UIComboBox(model); - layoutCombox.setSelectedIndex(1); - } - - @Override - public String title4PopupWindow() { - return "absoluteBodyLayout"; - } - - public void populateSubPane(WAbsoluteLayout ob) { - layoutCombox.setSelectedIndex(1); - themePane.supportFollowingTheme(ob.supportThemed()); - themePane.setFollowingTheme(ob.isBorderStyleFollowingTheme()); - stylePane.populateBean((LayoutBorderStyle) ob.getBorderStyle()); - watermarkEditor.setValue(ReportUtils.getWatermarkAttrFromTemplate(getCurrentIOFile())); - } - - public WAbsoluteBodyLayout updateSubPane() { - WAbsoluteBodyLayout layout = (WAbsoluteBodyLayout) creator.toData(); - Item item = (Item) layoutCombox.getSelectedItem(); - Object value = item.getValue(); - int state = 0; - if (value instanceof Integer) { - state = (Integer) value; - } - - if (layoutType == WBodyLayoutType.ABSOLUTE) { - ((XWFitLayout) creator.getBackupParent()).toData().resetStyle(); - if (state == WBodyLayoutType.FIT.getTypeValue()) { - XWFitLayout xwFitLayout = ((XWFitLayout)creator.getBackupParent()); - xwFitLayout.switch2FitBodyLayout(creator); - copyLayoutAttr(layout, xwFitLayout.toData()); - } - } - layout.setBorderStyleFollowingTheme(themePane.isFollowingTheme()); - layout.setBorderStyle(stylePane.updateBean()); - updateWatermark(); - return layout; - } - - private void updateWatermark() { - WatermarkAttr watermark = (WatermarkAttr) watermarkEditor.getValue(); - if (watermark != null) { - IOFile ioFile = getCurrentIOFile(); - ioFile.addAttrMark(watermark); - } - } - - private IOFile getCurrentIOFile() { - return WidgetPropertyPane.getInstance().getEditingFormDesigner().getTarget(); - } - - @Override - public DataCreatorUI dataUI() { - return null; - } - - -} diff --git a/designer-form/src/main/java/com/fr/design/fit/attrpane/FRAbsoluteLayoutExtendDefinePane.java b/designer-form/src/main/java/com/fr/design/fit/attrpane/FRAbsoluteLayoutExtendDefinePane.java deleted file mode 100644 index 60ffae3eb..000000000 --- a/designer-form/src/main/java/com/fr/design/fit/attrpane/FRAbsoluteLayoutExtendDefinePane.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.fr.design.fit.attrpane; - -import com.fr.design.designer.creator.XCreator; -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.widget.ui.designer.layout.AbstractFRLayoutDefinePane; -import com.fr.form.ui.container.WAbsoluteLayout; - -/** - * Created by kerry on 2020-04-22 - */ -public class FRAbsoluteLayoutExtendDefinePane extends AbstractFRLayoutDefinePane { - - public FRAbsoluteLayoutExtendDefinePane(XCreator xCreator) { - super(xCreator); - this.setLayout(FRGUIPaneFactory.createBorderLayout()); - } - - @Override - public void populateBean(WAbsoluteLayout ob) { - } - - @Override - public WAbsoluteLayout updateBean() { - WAbsoluteLayout wAbsoluteLayout = (WAbsoluteLayout) creator.toData(); - return wAbsoluteLayout; - } -} diff --git a/designer-form/src/main/java/com/fr/design/fit/attrpane/FRFitLayoutExtendDefinePane.java b/designer-form/src/main/java/com/fr/design/fit/attrpane/FRFitLayoutExtendDefinePane.java deleted file mode 100644 index 78e2c5c3a..000000000 --- a/designer-form/src/main/java/com/fr/design/fit/attrpane/FRFitLayoutExtendDefinePane.java +++ /dev/null @@ -1,282 +0,0 @@ -package com.fr.design.fit.attrpane; - - -import com.fr.base.io.IOFile; -import com.fr.base.iofile.attr.WatermarkAttr; -import com.fr.base.theme.FormTheme; -import com.fr.base.theme.TemplateTheme; -import com.fr.design.data.DataCreatorUI; -import com.fr.design.designer.IntervalConstants; -import com.fr.design.designer.creator.XCreator; -import com.fr.design.designer.creator.XLayoutContainer; -import com.fr.design.designer.creator.XWAbsoluteBodyLayout; -import com.fr.design.designer.creator.XWFitLayout; -import com.fr.design.designer.creator.XWScaleLayout; -import com.fr.design.designer.properties.items.FRLayoutTypeItems; -import com.fr.design.designer.properties.items.Item; -import com.fr.design.foldablepane.UIExpandablePane; -import com.fr.design.gui.icombobox.UIComboBox; -import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.ispinner.UISpinner; -import com.fr.design.gui.style.FollowingThemePane; -import com.fr.design.gui.xpane.LayoutStylePane; -import com.fr.design.i18n.Toolkit; -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.layout.TableLayoutHelper; -import com.fr.design.mainframe.FormDesigner; -import com.fr.design.mainframe.FormSelectionUtils; -import com.fr.design.mainframe.WidgetPropertyPane; -import com.fr.design.mainframe.widget.accessibles.AccessibleBodyWatermarkEditor; -import com.fr.design.utils.gui.UIComponentUtils; -import com.fr.design.widget.FRWidgetFactory; -import com.fr.design.widget.ui.designer.component.PaddingBoundPane; -import com.fr.design.widget.ui.designer.layout.AbstractFRLayoutDefinePane; -import com.fr.form.ui.LayoutBorderStyle; -import com.fr.form.ui.Widget; -import com.fr.form.ui.container.WAbsoluteBodyLayout; -import com.fr.form.ui.container.WAbsoluteLayout; -import com.fr.form.ui.container.WBodyLayoutType; -import com.fr.form.ui.container.WFitLayout; -import com.fr.general.ComparatorUtils; -import com.fr.general.act.BorderPacker; -import com.fr.log.FineLoggerFactory; -import com.fr.report.core.ReportUtils; - -import javax.swing.BorderFactory; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JPanel; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Dimension; - -/** - * Created by kerry on 2020-04-22 - */ -public class FRFitLayoutExtendDefinePane extends AbstractFRLayoutDefinePane { - private static final int ADAPT_LABEL_MAX_WIDTH = 80; - private XWFitLayout xWFitLayout; - private WFitLayout wFitLayout; - private UIComboBox layoutComboBox; - private UISpinner componentIntervel; - private PaddingBoundPane paddingBound; - private FollowingThemePane themePane; - private LayoutStylePane stylePane; - private AccessibleBodyWatermarkEditor watermarkEditor; - - public FRFitLayoutExtendDefinePane(XCreator xCreator) { - super(xCreator); - this.xWFitLayout = (XWFitLayout) xCreator; - wFitLayout = xWFitLayout.toData(); - initComponent(); - } - - - public void initComponent() { - this.setLayout(FRGUIPaneFactory.createBorderLayout()); - UIExpandablePane layoutExpandablePane = new UIExpandablePane( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout"), - 280, 20, - createLayoutPane() - ); - this.add(layoutExpandablePane, BorderLayout.NORTH); - - JPanel advancePane = createAdvancePane(); - UIExpandablePane advanceExpandablePane = new UIExpandablePane( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), - 280, 20, - advancePane - ); - this.add(advanceExpandablePane, BorderLayout.CENTER); - } - - public JPanel createAdvancePane() { - JPanel contentPane0 = FRGUIPaneFactory.createBorderLayout_S_Pane(); - - themePane = new FollowingThemePane(Toolkit.i18nText("Fine-Design_Form_Body_Style_Setting")); - stylePane = new LayoutStylePane(); - themePane.addFollowThemePane(stylePane, new FollowingThemePane.FollowingThemeActionChangeListener() { - @Override - public void onFollowingTheme(boolean following) { - stylePane.supportBodyStyle(!following); - - BorderPacker style = stylePane.updateBean(); - if (following) { - TemplateTheme theme = themePane.getUsingTheme(); - if (theme instanceof FormTheme) { - style = ((FormTheme) theme).getBodyStyle().merge(style); - } - } - stylePane.populateBean((LayoutBorderStyle) style); - } - }); - contentPane0.add(themePane, BorderLayout.NORTH); - - JPanel contentPane1 = FRGUIPaneFactory.createBorderLayout_S_Pane(); - contentPane0.add(contentPane1, BorderLayout.CENTER); - - watermarkEditor = new AccessibleBodyWatermarkEditor(); - JPanel waterMarkPane = TableLayoutHelper.createGapTableLayoutPane( - new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_WaterMark")), watermarkEditor} - }, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W3, IntervalConstants.INTERVAL_L1); - waterMarkPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); - contentPane1.add(waterMarkPane, BorderLayout.NORTH); - - paddingBound = new PaddingBoundPane(); - contentPane1.add(paddingBound, BorderLayout.CENTER); - - return contentPane0; - } - - public JPanel createLayoutPane() { - JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - - layoutComboBox = initUIComboBox(FRLayoutTypeItems.ITEMS); - componentIntervel = new UISpinner(0, Integer.MAX_VALUE, 1, 0); - JPanel componentIntervelPane = UIComponentUtils.wrapWithBorderLayoutPane(componentIntervel); - - UILabel intervalLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Component_Interval")); - - JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane( - new Component[][]{ - {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")), layoutComboBox}, - {intervalLabel, componentIntervelPane} - }, - TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); - contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); - containerPane.add(contentPane, BorderLayout.CENTER); - - return containerPane; - } - - - public UIComboBox initUIComboBox(Item[] items) { - DefaultComboBoxModel model = new DefaultComboBoxModel(); - for (Item item : items) { - model.addElement(item); - } - return new UIComboBox(model); - } - - - @Override - public String title4PopupWindow() { - return "fitLayout"; - } - - @Override - public void populateBean(WFitLayout ob) { - FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - XLayoutContainer rootLayout = selectedBodyLayout(formDesigner); - if (rootLayout != formDesigner.getRootComponent() - && formDesigner.getSelectionModel().getSelection().getSelectedCreator() == formDesigner.getRootComponent()) { - formDesigner.getSelectionModel().setSelectedCreators( - FormSelectionUtils.rebuildSelection(xWFitLayout, new Widget[]{selectedBodyLayout(formDesigner).toData()})); - - } - paddingBound.populate(ob); - layoutComboBox.setSelectedIndex(ob.getBodyLayoutType().getTypeValue()); - componentIntervel.setValue(ob.getCompInterval()); - themePane.supportFollowingTheme(ob.supportThemed()); - themePane.setFollowingTheme(ob.isBorderStyleFollowingTheme()); - stylePane.populateBean((LayoutBorderStyle) ob.getBorderStyle()); - watermarkEditor.setValue(ReportUtils.getWatermarkAttrFromTemplate(getCurrentIOFile())); - } - - private XLayoutContainer selectedBodyLayout(FormDesigner formDesigner) { - XLayoutContainer rootLayout = formDesigner.getRootComponent(); - if (rootLayout.getComponentCount() == 1 && rootLayout.getXCreator(0).acceptType(XWAbsoluteBodyLayout.class)) { - rootLayout = (XWAbsoluteBodyLayout) rootLayout.getXCreator(0); - } - return rootLayout; - } - - - @Override - public WFitLayout updateBean() { - WFitLayout layout = (WFitLayout) creator.toData(); - if (ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate"))) { - paddingBound.update(layout); - } - layout.setBorderStyleFollowingTheme(themePane.isFollowingTheme()); - LayoutBorderStyle borderStyle = stylePane.updateBean(); - if (borderStyle != null) { - layout.setBorderStyle(borderStyle); - } - updateWatermark(); - Item item = (Item) layoutComboBox.getSelectedItem(); - Object value = item.getValue(); - int state = 0; - if (value instanceof Integer) { - state = (Integer) value; - } - //todo 验证下 - layout.setLayoutType(WBodyLayoutType.parse(state)); - try { - if (state == WBodyLayoutType.ABSOLUTE.getTypeValue()) { - WAbsoluteBodyLayout wAbsoluteBodyLayout = new WAbsoluteBodyLayout("body"); - wAbsoluteBodyLayout.setCompState(WAbsoluteLayout.STATE_FIXED); - Component[] components = xWFitLayout.getComponents(); - xWFitLayout.removeAll(); - layout.resetStyle(); - XWAbsoluteBodyLayout xwAbsoluteBodyLayout = xWFitLayout.getBackupParent() == null ? new XWAbsoluteBodyLayout(wAbsoluteBodyLayout, new Dimension(0, 0)) : (XWAbsoluteBodyLayout) xWFitLayout.getBackupParent(); - xWFitLayout.getLayoutAdapter().addBean(xwAbsoluteBodyLayout, 0, 0); - for (Component component : components) { - XCreator xCreator = (XCreator) component; - //部分控件被ScaleLayout包裹着,绝对布局里面要放出来 - if (xCreator.acceptType(XWScaleLayout.class)) { - if (xCreator.getComponentCount() > 0 && ((XCreator) xCreator.getComponent(0)).shouldScaleCreator()) { - component = xCreator.getComponent(0); - component.setBounds(xCreator.getBounds()); - } - } - xwAbsoluteBodyLayout.add(component); - } - copyLayoutAttr(wFitLayout, wAbsoluteBodyLayout); - xWFitLayout.setBackupParent(xwAbsoluteBodyLayout); - FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - formDesigner.getSelectionModel().setSelectedCreators( - FormSelectionUtils.rebuildSelection(xWFitLayout, new Widget[]{wAbsoluteBodyLayout})); - } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - - } - - int intervelValue = (int) componentIntervel.getValue(); - if (xWFitLayout.canAddInterval(intervelValue)) { -// 设置完间隔后,要同步处理界面组件,容器刷新后显示出对应效果 - setLayoutGap(intervelValue); - } - - return layout; - } - - private void updateWatermark() { - WatermarkAttr watermark = (WatermarkAttr) watermarkEditor.getValue(); - if (watermark != null) { - IOFile ioFile = getCurrentIOFile(); - ioFile.addAttrMark(watermark); - } - } - - private IOFile getCurrentIOFile() { - return WidgetPropertyPane.getInstance().getEditingFormDesigner().getTarget(); - } - - private void setLayoutGap(int value) { - int interval = wFitLayout.getCompInterval(); - if (value != interval) { - xWFitLayout.moveContainerMargin(); - xWFitLayout.moveCompInterval(xWFitLayout.getAcualInterval()); - wFitLayout.setCompInterval(value); - xWFitLayout.addCompInterval(xWFitLayout.getAcualInterval()); - } - } - - @Override - public DataCreatorUI dataUI() { - return null; - } - -} diff --git a/designer-form/src/main/java/com/fr/design/fit/attrpane/RootDesignExtendDefinePane.java b/designer-form/src/main/java/com/fr/design/fit/attrpane/RootDesignExtendDefinePane.java deleted file mode 100644 index 8a8aa404a..000000000 --- a/designer-form/src/main/java/com/fr/design/fit/attrpane/RootDesignExtendDefinePane.java +++ /dev/null @@ -1,303 +0,0 @@ -package com.fr.design.fit.attrpane; - -import com.fr.base.BaseUtils; -import com.fr.design.ExtraDesignClassManager; -import com.fr.design.data.DataCreatorUI; -import com.fr.design.designer.IntervalConstants; -import com.fr.design.designer.creator.CRPropertyDescriptor; -import com.fr.design.designer.creator.PropertyGroupPane; -import com.fr.design.designer.creator.XCreator; -import com.fr.design.designer.creator.XWParameterLayout; -import com.fr.design.designer.properties.PropertyTab; -import com.fr.design.file.HistoryTemplateListPane; -import com.fr.design.fit.DesignerUIModeConfig; -import com.fr.design.fit.common.TemplateTool; -import com.fr.design.foldablepane.UIExpandablePane; -import com.fr.design.fun.ParameterExpandablePaneUIProvider; -import com.fr.design.gui.ibutton.UIButtonGroup; -import com.fr.design.gui.icheckbox.UICheckBox; -import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.ispinner.UISpinner; -import com.fr.design.gui.itextfield.UITextField; -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.layout.TableLayout; -import com.fr.design.layout.TableLayoutHelper; -import com.fr.design.mainframe.FormDesigner; -import com.fr.design.mainframe.FormSelection; -import com.fr.design.mainframe.JTemplate; -import com.fr.design.mainframe.widget.accessibles.AccessibleBackgroundEditor; -import com.fr.design.utils.gui.LayoutUtils; -import com.fr.design.utils.gui.UIComponentUtils; -import com.fr.design.widget.ui.designer.AbstractDataModify; -import com.fr.design.widget.ui.designer.component.UIBoundSpinner; -import com.fr.form.ui.container.WParameterLayout; -import com.fr.general.Background; -import com.fr.report.stable.FormConstants; - -import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.JPanel; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Rectangle; -import java.util.Set; - -public class RootDesignExtendDefinePane extends AbstractDataModify { - private XWParameterLayout root; - private UISpinner designerWidth; - private UISpinner paraHeight; - private UICheckBox displayReport; - private UICheckBox useParamsTemplate; - private AccessibleBackgroundEditor background; - private UIButtonGroup hAlignmentPane; - private UITextField labelNameTextField; - //是否是新设计模式下决策报表 - private boolean newForm; - private PropertyGroupPane extraPropertyGroupPane; - - public RootDesignExtendDefinePane(XCreator xCreator) { - super(xCreator); - newForm = TemplateTool.getCurrentEditingNewJForm() != null && DesignerUIModeConfig.getInstance().newUIMode(); - this.root = (XWParameterLayout) xCreator; - initComponent(); - } - - - public void initComponent() { - this.setLayout(FRGUIPaneFactory.createBorderLayout()); - if (newForm) { - paraHeight = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0); - } else { - designerWidth = new UIBoundSpinner(1, Integer.MAX_VALUE, 1); - } - JPanel advancePane = createAdvancePane(); - UIExpandablePane advanceExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), 280, 20, advancePane); - this.add(advanceExpandablePane, BorderLayout.NORTH); - JPanel layoutPane = createBoundsPane(); - UIExpandablePane layoutExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Size"), 280, 20, layoutPane); - this.add(layoutExpandablePane, BorderLayout.CENTER); - this.addExtraUIExpandablePaneFromPlugin(); - } - - private void addExtraUIExpandablePaneFromPlugin() { - Set pluginCreators = ExtraDesignClassManager.getInstance().getArray(ParameterExpandablePaneUIProvider.XML_TAG); - JPanel panel = FRGUIPaneFactory.createYBoxEmptyBorderPane(); - for (ParameterExpandablePaneUIProvider provider : pluginCreators) { - UIExpandablePane uiExpandablePane = provider.createUIExpandablePane(); - PropertyTab propertyTab = provider.addToWhichPropertyTab(); - if (uiExpandablePane != null && propertyTab == PropertyTab.ATTR) { - panel.add(uiExpandablePane); - } - } - this.add(panel, BorderLayout.SOUTH); - } - - public JPanel createBoundsPane() { - double f = TableLayout.FILL; - double p = TableLayout.PREFERRED; - double[] rowSize = {p}; - double[] columnSize = {p, f}; - int[][] rowCount = {{1, 1}}; - Component[] component = newForm ? new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Design_Height")), paraHeight} : - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Desin_Width")), designerWidth}; - Component[][] components = new Component[][]{component}; - JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); - JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); - panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); - jPanel.add(panel); - return jPanel; - } - - public JPanel createAdvancePane() { - if (newForm) { - return getNewFormAdvancePane(); - } else { - return getTemplateAdvancePane(); - } - } - - /** - * @Description: 获取的非新决策报表AdvancePane - * @param - * @return: - * @Author: Henry.Wang - * @date: 2020/11/05 15:36 - */ - private JPanel getTemplateAdvancePane() { - JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); - labelNameTextField = new UITextField(); - displayReport = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Display_Nothing_Before_Query")); - UIComponentUtils.setLineWrap(displayReport); - useParamsTemplate = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Use_Params_Template")); - background = new AccessibleBackgroundEditor(); - Icon[] hAlignmentIconArray = {BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_left_normal.png"), - BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_center_normal.png"), - BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_right_normal.png"),}; - Integer[] hAlignment = new Integer[]{FormConstants.LEFTPOSITION, FormConstants.CENTERPOSITION, FormConstants.RIGHTPOSITION}; - hAlignmentPane = new UIButtonGroup(hAlignmentIconArray, hAlignment); - hAlignmentPane.setAllToolTips(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Left") - , com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Center"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Right")}); - double f = TableLayout.FILL; - double p = TableLayout.PREFERRED; - double[] rowSize = {p, p, p, p, p}; - double[] columnSize = {p, f}; - int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}; - Component[][] components = new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Label_Name")), labelNameTextField}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Base_Background")), background}, - new Component[]{displayReport, null}, - new Component[]{useParamsTemplate, null}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Display_Position")), hAlignmentPane} - }; - JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_L1); - panel.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); - CRPropertyDescriptor[] extraTableEditor = new CRPropertyDescriptor[0]; - extraTableEditor = root.getExtraTableEditor(); - extraPropertyGroupPane = new PropertyGroupPane(extraTableEditor, root); - - jPanel.add(panel, BorderLayout.NORTH); - jPanel.add(extraPropertyGroupPane, BorderLayout.CENTER); - return jPanel; - } - - /** - * @Description: 获取新决策报表的AdvancePane - * @param - * @return: - * @Author: Henry.Wang - * @date: 2020/11/05 15:36 - */ - private JPanel getNewFormAdvancePane() { - JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); - labelNameTextField = new UITextField(); - displayReport = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Display_Nothing_Before_Query")); - UIComponentUtils.setLineWrap(displayReport); - useParamsTemplate = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Use_Params_Template")); - background = new AccessibleBackgroundEditor(); - - double f = TableLayout.FILL; - double p = TableLayout.PREFERRED; - double[] rowSize = {p, p, p, p}; - double[] columnSize = {p, f}; - int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}}; - Component[][] components = new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Label_Name")), labelNameTextField}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Base_Background")), background}, - new Component[]{displayReport, null}, - new Component[]{useParamsTemplate, null} - }; - JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_L1); - panel.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); - - jPanel.add(panel, BorderLayout.NORTH); - - return jPanel; - } - - @Override - public String title4PopupWindow() { - return "parameter"; - } - - @Override - public void populateBean(WParameterLayout ob) { - labelNameTextField.setText(ob.getLabelName()); - background.setValue(ob.getBackground()); - displayReport.setSelected(ob.isDelayDisplayContent()); - useParamsTemplate.setSelected(ob.isUseParamsTemplate()); - if (newForm) { - FormDesigner designer = TemplateTool.getCurrentEditingNewJForm().getFormDesign(); - paraHeight.setValue(designer.getParaHeight()); - } else { - designerWidth.setValue(ob.getDesignWidth()); - hAlignmentPane.setSelectedItem(ob.getPosition()); - - if (extraPropertyGroupPane != null) { - extraPropertyGroupPane.populate(ob); - } - } - } - - - @Override - public WParameterLayout updateBean() { - if (newForm) { - return updateNewFormBean(); - } else { - return updateTemplateBean(); - } - } - - /** - * @Description: 更新非新决策报表的bean - * @param - * @return: - * @Author: Henry.Wang - * @date: 2020/11/05 15:36 - */ - private WParameterLayout updateTemplateBean() { - WParameterLayout wParameterLayout = (WParameterLayout) creator.toData(); - wParameterLayout.setLabelName(labelNameTextField.getText()); - if (isCompsOutOfDesignerWidth((int) designerWidth.getValue())) { - designerWidth.setValue(wParameterLayout.getDesignWidth()); - } else { - wParameterLayout.setDesignWidth((int) designerWidth.getValue()); - } - wParameterLayout.setDelayDisplayContent(displayReport.isSelected()); - wParameterLayout.setUseParamsTemplate(useParamsTemplate.isSelected()); - JTemplate jTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); - jTemplate.needAddTemplateIdAttr(useParamsTemplate.isSelected()); - wParameterLayout.setBackground((Background) background.getValue()); - wParameterLayout.setPosition((Integer) hAlignmentPane.getSelectedItem()); - return wParameterLayout; - } - - /** - * @Description: 更新新决策报表的bean - * @param - * @return: - * @Author: Henry.Wang - * @date: 2020/11/05 15:36 - */ - private WParameterLayout updateNewFormBean() { - WParameterLayout wParameterLayout = (WParameterLayout) creator.toData(); - wParameterLayout.setLabelName(labelNameTextField.getText()); - - wParameterLayout.setDelayDisplayContent(displayReport.isSelected()); - wParameterLayout.setUseParamsTemplate(useParamsTemplate.isSelected()); - JTemplate jTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); - jTemplate.needAddTemplateIdAttr(useParamsTemplate.isSelected()); - wParameterLayout.setBackground((Background) background.getValue()); - //设置参数模板面板的高度 - int height = (int) paraHeight.getTextField().getValue(); - FormDesigner designer = TemplateTool.getCurrentEditingNewJForm().getFormDesign(); - FormSelection selection = designer.getSelectionModel().getSelection(); - XCreator creator = designer.getParaComponent(); - Rectangle rectangle = creator.getBounds(); - Rectangle newRectangle = new Rectangle(rectangle.x, rectangle.y, rectangle.width, height); - creator.setBounds(newRectangle); - if (paraHeight.getValue() != newRectangle.height) - paraHeight.setValue(newRectangle.height); - designer.setParaHeight(newRectangle.height); - designer.getArea().doLayout(); - LayoutUtils.layoutContainer(creator); - selection.fixCreator(designer); - designer.repaint(); - return wParameterLayout; - } - - private boolean isCompsOutOfDesignerWidth(int designerWidth) { - for (int i = 0; i < root.getComponentCount(); i++) { - Component comp = root.getComponent(i); - if (comp.getX() + comp.getWidth() > designerWidth) { - return true; - } - } - return false; - } - - @Override - public DataCreatorUI dataUI() { - return null; - } -} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/fit/common/AdaptiveSwitchUtil.java b/designer-form/src/main/java/com/fr/design/fit/common/AdaptiveSwitchUtil.java index 8c55e8ab0..a5df5fabd 100644 --- a/designer-form/src/main/java/com/fr/design/fit/common/AdaptiveSwitchUtil.java +++ b/designer-form/src/main/java/com/fr/design/fit/common/AdaptiveSwitchUtil.java @@ -3,39 +3,24 @@ package com.fr.design.fit.common; import com.fr.design.data.DesignTableDataManager; import com.fr.design.fit.DesignerUIModeConfig; import com.fr.design.fit.NewJForm; -import com.fr.design.fit.attrpane.ElementEditorExtendDefinePane; -import com.fr.design.fit.attrpane.FRAbsoluteBodyLayoutExtendDefinePane; -import com.fr.design.fit.attrpane.FRAbsoluteLayoutExtendDefinePane; -import com.fr.design.fit.attrpane.FRFitLayoutExtendDefinePane; -import com.fr.design.fit.attrpane.RootDesignExtendDefinePane; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.JForm; import com.fr.design.mainframe.JTemplate; -import com.fr.design.parameter.RootDesignDefinePane; import com.fr.design.preview.FormAdaptivePreview; import com.fr.design.preview.FormPreview; -import com.fr.design.widget.Appearance; -import com.fr.design.widget.FormWidgetDefinePaneFactoryBase; -import com.fr.design.widget.ui.designer.layout.ElementEditorDefinePane; -import com.fr.design.widget.ui.designer.layout.FRAbsoluteBodyLayoutDefinePane; -import com.fr.design.widget.ui.designer.layout.FRAbsoluteLayoutDefinePane; -import com.fr.design.widget.ui.designer.layout.FRFitLayoutDefinePane; import com.fr.file.FILE; import com.fr.file.MemFILE; import com.fr.form.main.Form; import com.fr.form.main.WidgetGather; -import com.fr.form.ui.ElementCaseEditor; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WAbsoluteBodyLayout; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WFitLayout; -import com.fr.form.ui.container.WParameterLayout; import com.fr.form.ui.widget.CRBoundsWidget; import com.fr.log.FineLoggerFactory; import com.fr.report.fit.ReportFitAttr; import javax.swing.SwingUtilities; -import java.util.Set; /** * Created by kerry on 2020-06-02 @@ -55,16 +40,6 @@ public class AdaptiveSwitchUtil { public static void switch2NewUIMode() { DesignerUIModeConfig.getInstance().setNewUIMode(); - FormWidgetDefinePaneFactoryBase.registerDefinePane(ElementCaseEditor.class, - new Appearance(ElementEditorExtendDefinePane.class, "elementCaseEditor")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WFitLayout.class, - new Appearance(FRFitLayoutExtendDefinePane.class, "wFitLayout")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WAbsoluteBodyLayout.class, - new Appearance(FRAbsoluteBodyLayoutExtendDefinePane.class, "wAbsoluteBodyLayout")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WAbsoluteLayout.class, - new Appearance(FRAbsoluteLayoutExtendDefinePane.class, "wAbsoluteLayout")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WParameterLayout.class, - new Appearance(RootDesignExtendDefinePane.class, "wParameterLayout")); } public static void switch2OldUI() { @@ -74,16 +49,6 @@ public class AdaptiveSwitchUtil { public static void switch2OldUIMode() { DesignerUIModeConfig.getInstance().setOldUIMode(); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WAbsoluteLayout.class, - new Appearance(FRAbsoluteLayoutDefinePane.class, "wAbsoluteLayout")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(ElementCaseEditor.class, - new Appearance(ElementEditorDefinePane.class, "elementCaseEditor")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WAbsoluteBodyLayout.class, - new Appearance(FRAbsoluteBodyLayoutDefinePane.class, "wAbsoluteBodyLayout")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WFitLayout.class, - new Appearance(FRFitLayoutDefinePane.class, "wFitLayout")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WParameterLayout.class, - new Appearance(RootDesignDefinePane.class, "wParameterLayout")); } public static void reload() { diff --git a/designer-form/src/main/java/com/fr/design/form/layout/FRTitleLayout.java b/designer-form/src/main/java/com/fr/design/form/layout/FRTitleLayout.java index 3f0d2826f..2be67555a 100644 --- a/designer-form/src/main/java/com/fr/design/form/layout/FRTitleLayout.java +++ b/designer-form/src/main/java/com/fr/design/form/layout/FRTitleLayout.java @@ -6,6 +6,7 @@ package com.fr.design.form.layout; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; +import java.awt.Insets; import java.awt.LayoutManager; import com.fr.form.ui.container.WLayout; @@ -123,15 +124,20 @@ public class FRTitleLayout implements FRLayoutManager, LayoutManager{ synchronized (target.getTreeLock()) { int width = target.getWidth(); int height = target.getHeight(); - int titleH = title==null ? 0 : WTitleLayout.TITLE_HEIGHT; + Insets insets = target.getInsets(); + int titleH = title == null ? 0 : WTitleLayout.TITLE_HEIGHT; + insets = title == null ? new Insets(0, 0, 0, 0) : insets; + width = Math.max(0, width - insets.left - insets.right); + height = Math.max(0, height - insets.top - insets.bottom); + for (int i=0; i< target.getComponentCount(); i++) { Component comp = target.getComponent(i); if (comp != null) { if (comp == title) { - comp.setBounds(0, 0, width, WTitleLayout.TITLE_HEIGHT); + comp.setBounds(insets.left, insets.top, width, WTitleLayout.TITLE_HEIGHT); } else if (comp == body) { int y = titleH + gap; - comp.setBounds(0, y, width, height-y); + comp.setBounds(insets.left, y + insets.top, width, height - y); } } } diff --git a/designer-form/src/main/java/com/fr/design/form/parameter/FormParaTargetMode.java b/designer-form/src/main/java/com/fr/design/form/parameter/FormParaTargetMode.java index 72c7b8bfd..02ea653f2 100644 --- a/designer-form/src/main/java/com/fr/design/form/parameter/FormParaTargetMode.java +++ b/designer-form/src/main/java/com/fr/design/form/parameter/FormParaTargetMode.java @@ -1,7 +1,6 @@ package com.fr.design.form.parameter; -import com.fr.base.svg.IconUtils; import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.properties.WidgetPropertyTable; import com.fr.design.gui.core.WidgetOption; @@ -12,6 +11,7 @@ import com.fr.form.main.parameter.FormParameterUI; import com.fr.form.parameter.FormSubmitButton; +import com.fr.form.ui.PageFixedRowComboBox; import java.util.ArrayList; public class FormParaTargetMode extends FormDesignerModeForSpecial { @@ -28,7 +28,9 @@ public class FormParaTargetMode extends FormDesignerModeForSpecial { namedIntegralStylePane.setVisible(supporting); } } -} +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java b/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java index 2d0bb383f..0c8649348 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java @@ -13,11 +13,8 @@ import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.gui.itree.UITreeUI; import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.GUICoreUtils; -import com.fr.stable.ArrayUtils; import com.fr.stable.StringUtils; - import java.awt.Rectangle; -import java.awt.event.MouseListener; import java.util.Stack; import java.util.function.Consumer; import javax.swing.BorderFactory; @@ -98,6 +95,10 @@ public class ComponentTree extends JTree { public void setSelectionPath(TreePath path) { // 不管点击哪一项,都要先退出编辑状态(图表、报表块、绝对布局、tab块) + Object widget = path.getLastPathComponent(); + if(widget == null ||!((XCreator)widget).getXCreatorBaseOperate().supportSelected()){ + return; + } designer.stopEditing(path); super.setSelectionPath(path); } @@ -361,7 +362,6 @@ public class ComponentTree extends JTree { @Override public void mouseMoved(MouseEvent e) { - Point p = e.getPoint(); int selRow = tree.getRowForLocation(p.x, p.y); TreeCellRenderer r = tree.getCellRenderer(); @@ -370,10 +370,12 @@ public class ComponentTree extends JTree { Point point = tree.getPathBounds(path).getLocation(); SwingUtilities.convertPointToScreen(point, tree); XCreator comp = (XCreator) path.getLastPathComponent(); - popupPreviewPane(point.y, comp); - } else { - hidePreviewPane(); + if (comp.getXCreatorBaseOperate().supportSelected()) { + popupPreviewPane(point.y, comp); + return; + } } + hidePreviewPane(); } @Override @@ -386,8 +388,9 @@ public class ComponentTree extends JTree { onMouseEvent(e, new Consumer() { @Override public void accept(XCreator creator) { - if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1 && !designer.isFormParaDesigner()) { - startEditing(creator, e); + if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1 && !designer.isFormParaDesigner() + &&creator.getXCreatorBaseOperate().supportSelected()) { + startEditing(creator); } } }); @@ -399,7 +402,7 @@ public class ComponentTree extends JTree { onMouseEvent(e, new Consumer() { @Override public void accept(XCreator creator) { - if (e.getButton() == MouseEvent.BUTTON1) { + if (e.getButton() == MouseEvent.BUTTON1 && creator.getXCreatorBaseOperate().supportSelected()) { selectedCreator = creator; } } @@ -455,18 +458,11 @@ public class ComponentTree extends JTree { * 组件进入编辑状态 * * @param comp - * @param e */ - private void startEditing(XCreator comp, MouseEvent e) { + private void startEditing(XCreator comp) { designer.getSelectionModel().selectACreator(comp); - Rectangle rectangle = getRelativeBounds(comp); - int x = rectangle.x + rectangle.width / 2; - int y = rectangle.y + rectangle.height / 2; XCreator creator = comp.getEditingChildCreator(); - MouseListener[] listeners = designer.getMouseListeners(); - if (ArrayUtils.isNotEmpty(listeners) && listeners[0] instanceof EditingMouseListener) { - responseClickAll(creator, (EditingMouseListener) listeners[0], new MouseEvent(creator, MouseEvent.MOUSE_CLICKED, e.getWhen(), e.getModifiers(), x, y, e.getClickCount(), false)); - } + responseEditing(creator); // 放到事件尾部执行 SwingUtilities.invokeLater(new Runnable() { @Override @@ -488,10 +484,8 @@ public class ComponentTree extends JTree { * * * @param creator - * @param editingMouseListener - * @param mouseEvent */ - public void responseClickAll(XCreator creator, EditingMouseListener editingMouseListener, MouseEvent mouseEvent) { + private void responseEditing(XCreator creator) { Stack stack = new Stack<>(); stack.push(creator); while (creator.getParent() instanceof XCreator) { @@ -499,7 +493,7 @@ public class ComponentTree extends JTree { stack.push(creator); } while (!stack.isEmpty()) { - stack.pop().respondClick(editingMouseListener, mouseEvent); + stack.pop().startEditing(); } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/DesignerScaleMouseWheelHandler.java b/designer-form/src/main/java/com/fr/design/mainframe/DesignerScaleMouseWheelHandler.java new file mode 100644 index 000000000..15aec31d5 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/DesignerScaleMouseWheelHandler.java @@ -0,0 +1,31 @@ +package com.fr.design.mainframe; + +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/23 + */ +public class DesignerScaleMouseWheelHandler implements MouseWheelListener { + private final ScalePane scalePane; + private final int step; + + public DesignerScaleMouseWheelHandler(ScalePane scalePane, int step) { + this.scalePane = scalePane; + this.step = step; + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + int dir = e.getWheelRotation(); + JFormSliderPane slidePane = this.scalePane.getSlidePane(); + int old_resolution = slidePane.getShowValue(); + slidePane.setShowValue(old_resolution - (dir * step)); + } + + public interface ScalePane { + JFormSliderPane getSlidePane(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/DesignerTranslateMouseWheelHandler.java b/designer-form/src/main/java/com/fr/design/mainframe/DesignerTranslateMouseWheelHandler.java new file mode 100644 index 000000000..82d2cb1b8 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/DesignerTranslateMouseWheelHandler.java @@ -0,0 +1,279 @@ +package com.fr.design.mainframe; + +import javax.swing.JScrollBar; +import javax.swing.JViewport; +import javax.swing.Scrollable; +import javax.swing.SwingConstants; +import java.awt.Component; +import java.awt.Rectangle; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +/** + * 实现设计器面板的触摸板滚动移动交互 https://work.fineres.com/browse/REPORT-55989 + * + * mouseWheelMoved 的具体实现来自 + * @link {javax.swing.plaf.basic.BasicScrollPaneUI.Handler#mouseWheelMoved} + * scrollByUnits 的具体实现来自 + * @link {javax.swing.plaf.basic.BasicScrollPaneUI#scrollByUnits} + * scrollByBlock 的具体实现来自 + * @link {javax.swing.plaf.basic.BasicScrollPaneUI#scrollByBlock} + */ +public class DesignerTranslateMouseWheelHandler implements MouseWheelListener { + private final ScrollPane scrollpane; + + public DesignerTranslateMouseWheelHandler(ScrollPane scrollpane) { + this.scrollpane = scrollpane; + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if (scrollpane.isWheelScrollingEnabled() && + e.getWheelRotation() != 0) { + JScrollBar toScroll = scrollpane.getVerticalScrollBar(); + int direction = e.getWheelRotation() < 0 ? -1 : 1; + int orientation = SwingConstants.VERTICAL; + + // find which scrollbar to scroll, or return if none + if (toScroll == null || !toScroll.isVisible() + || e.isShiftDown()) { + toScroll = scrollpane.getHorizontalScrollBar(); + if (toScroll == null || !toScroll.isVisible()) { + return; + } + orientation = SwingConstants.HORIZONTAL; + } + + e.consume(); + + if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { + JViewport vp = scrollpane.getViewport(); + if (vp == null) { return; } + Component comp = vp.getView(); + int units = Math.abs(e.getUnitsToScroll()); + + // When the scrolling speed is set to maximum, it's possible + // for a single wheel click to scroll by more units than + // will fit in the visible area. This makes it + // hard/impossible to get to certain parts of the scrolling + // Component with the wheel. To make for more accurate + // low-speed scrolling, we limit scrolling to the block + // increment if the wheel was only rotated one click. + boolean limitScroll = Math.abs(e.getWheelRotation()) == 1; + + // Check if we should use the visibleRect trick + Object fastWheelScroll = toScroll.getClientProperty( + "JScrollBar.fastWheelScrolling"); + if (Boolean.TRUE == fastWheelScroll && + comp instanceof Scrollable) { + // 5078454: Under maximum acceleration, we may scroll + // by many 100s of units in ~1 second. + // + // BasicScrollBarUI.scrollByUnits() can bog down the EDT + // with repaints in this situation. However, the + // Scrollable interface allows us to pass in an + // arbitrary visibleRect. This allows us to accurately + // calculate the total scroll amount, and then update + // the GUI once. This technique provides much faster + // accelerated wheel scrolling. + Scrollable scrollComp = (Scrollable) comp; + Rectangle viewRect = vp.getViewRect(); + int startingX = viewRect.x; + boolean leftToRight = + comp.getComponentOrientation().isLeftToRight(); + int scrollMin = toScroll.getMinimum(); + int scrollMax = toScroll.getMaximum() - + toScroll.getModel().getExtent(); + + if (limitScroll) { + int blockIncr = + scrollComp.getScrollableBlockIncrement(viewRect, + orientation, + direction); + if (direction < 0) { + scrollMin = Math.max(scrollMin, + toScroll.getValue() - blockIncr); + } + else { + scrollMax = Math.min(scrollMax, + toScroll.getValue() + blockIncr); + } + } + + for (int i = 0; i < units; i++) { + int unitIncr = + scrollComp.getScrollableUnitIncrement(viewRect, + orientation, direction); + // Modify the visible rect for the next unit, and + // check to see if we're at the end already. + if (orientation == SwingConstants.VERTICAL) { + if (direction < 0) { + viewRect.y -= unitIncr; + if (viewRect.y <= scrollMin) { + viewRect.y = scrollMin; + break; + } + } + else { // (direction > 0 + viewRect.y += unitIncr; + if (viewRect.y >= scrollMax) { + viewRect.y = scrollMax; + break; + } + } + } + else { + // Scroll left + if ((leftToRight && direction < 0) || + (!leftToRight && direction > 0)) { + viewRect.x -= unitIncr; + if (leftToRight) { + if (viewRect.x < scrollMin) { + viewRect.x = scrollMin; + break; + } + } + } + // Scroll right + else if ((leftToRight && direction > 0) || + (!leftToRight && direction < 0)) { + viewRect.x += unitIncr; + if (leftToRight) { + if (viewRect.x > scrollMax) { + viewRect.x = scrollMax; + break; + } + } + } + else { + assert false : "Non-sensical ComponentOrientation / scroll direction"; + } + } + } + // Set the final view position on the ScrollBar + if (orientation == SwingConstants.VERTICAL) { + toScroll.setValue(viewRect.y); + } + else { + if (leftToRight) { + toScroll.setValue(viewRect.x); + } + else { + // rightToLeft scrollbars are oriented with + // minValue on the right and maxValue on the + // left. + int newPos = toScroll.getValue() - + (viewRect.x - startingX); + if (newPos < scrollMin) { + newPos = scrollMin; + } + else if (newPos > scrollMax) { + newPos = scrollMax; + } + toScroll.setValue(newPos); + } + } + } + else { + // Viewport's view is not a Scrollable, or fast wheel + // scrolling is not enabled. + scrollByUnits(toScroll, direction, + units, limitScroll); + } + } + else if (e.getScrollType() == + MouseWheelEvent.WHEEL_BLOCK_SCROLL) { + scrollByBlock(toScroll, direction); + } + } + } + + /* + * Method for scrolling by a unit increment. + * Added for mouse wheel scrolling support, RFE 4202656. + * + * If limitByBlock is set to true, the scrollbar will scroll at least 1 + * unit increment, but will not scroll farther than the block increment. + * See BasicScrollPaneUI.Handler.mouseWheelMoved(). + */ + static void scrollByUnits(JScrollBar scrollbar, int direction, + int units, boolean limitToBlock) { + // This method is called from BasicScrollPaneUI to implement wheel + // scrolling, as well as from scrollByUnit(). + int delta; + int limit = -1; + + if (limitToBlock) { + if (direction < 0) { + limit = scrollbar.getValue() - + scrollbar.getBlockIncrement(direction); + } + else { + limit = scrollbar.getValue() + + scrollbar.getBlockIncrement(direction); + } + } + + for (int i=0; i 0) { + delta = scrollbar.getUnitIncrement(direction); + } + else { + delta = -scrollbar.getUnitIncrement(direction); + } + + int oldValue = scrollbar.getValue(); + int newValue = oldValue + delta; + + // Check for overflow. + if (delta > 0 && newValue < oldValue) { + newValue = scrollbar.getMaximum(); + } + else if (delta < 0 && newValue > oldValue) { + newValue = scrollbar.getMinimum(); + } + if (oldValue == newValue) { + break; + } + + if (limitToBlock && i > 0) { + assert limit != -1; + if ((direction < 0 && newValue < limit) || + (direction > 0 && newValue > limit)) { + break; + } + } + scrollbar.setValue(newValue); + } + } + + /* + * Method for scrolling by a block increment. + * Added for mouse wheel scrolling support, RFE 4202656. + */ + static void scrollByBlock(JScrollBar scrollbar, int direction) { + // This method is called from BasicScrollPaneUI to implement wheel + // scrolling, and also from scrollByBlock(). + int oldValue = scrollbar.getValue(); + int blockIncrement = scrollbar.getBlockIncrement(direction); + int delta = blockIncrement * ((direction > 0) ? +1 : -1); + int newValue = oldValue + delta; + + // Check for overflow. + if (delta > 0 && newValue < oldValue) { + newValue = scrollbar.getMaximum(); + } + else if (delta < 0 && newValue > oldValue) { + newValue = scrollbar.getMinimum(); + } + + scrollbar.setValue(newValue); + } + + public interface ScrollPane { + boolean isWheelScrollingEnabled(); + JScrollBar getVerticalScrollBar(); + JScrollBar getHorizontalScrollBar(); + JViewport getViewport(); + } +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java b/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java index a7244c0f2..b0463a685 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java @@ -636,7 +636,7 @@ public class EditingMouseListener extends MouseInputAdapter { XCreator oldCreator = creator; creator = processTopLayoutMouseClick(creator); - if (creator != null) { + if (creator != null && creator.getXCreatorBaseOperate().supportSelected()) { // tab块处于未编辑状态 boolean uneditedTab = designer.getCursor().getType() != Cursor.HAND_CURSOR && creator.acceptType(XWCardMainBorderLayout.class) && !((XWCardMainBorderLayout) creator).isEditable(); // 点击不在tab块的button中 diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java b/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java index 16dc8593e..e08c1c652 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java @@ -1,12 +1,21 @@ package com.fr.design.mainframe; import com.fr.common.inputevent.InputEventBaseOnOS; +import com.fr.design.actions.UpdateAction; +import com.fr.design.constants.UIConstants; import com.fr.design.designer.beans.events.DesignerEvent; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWBorderLayout; import com.fr.design.designer.creator.XWFitLayout; import com.fr.design.fit.DesignerUIModeConfig; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIButtonUI; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.PopupMenuItem; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.design.utils.gui.GUIPaintUtils; import com.fr.form.fit.NewFormMarkAttr; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itextfield.UINumberField; @@ -20,15 +29,20 @@ import com.fr.design.scrollruler.VerticalRuler; import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.LayoutUtils; import com.fr.form.main.mobile.FormMobileAttr; +import com.fr.form.ui.container.WBodyLayoutType; import com.fr.form.ui.container.WBorderLayout; -import com.fr.general.FRScreen; +import com.fr.form.ui.container.WFitLayout; +import com.fr.general.IOUtils; import com.fr.stable.AssistUtils; import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.KeyStroke; +import javax.swing.SwingConstants; import javax.swing.border.LineBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -38,6 +52,8 @@ import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; @@ -58,10 +74,11 @@ public class FormArea extends JComponent implements ScrollRulerComponent { private static final double SLIDER_MIN = 10.0; private static final String SCALE_PLUS_COMMAND = "scale_plus"; private static final String SCALE_MINUS_COMMAND = "scale_minus"; + public static final String FIX_LAYOUT_SWITCH_BUTTON = "fix_layout_switch_button"; public static final double DEFAULT_SLIDER = 100.0; private static final int ROTATIONS = 50; - private static final int SHOWVALMAX = 400; - private static final int SHOWVALMIN = 10; + public static final int SHOWVALMAX = 400; + public static final int SHOWVALMIN = 10; private static final int RESIZE_PANE_GAP = 8; private static final int MOBILE_ONLY_WIDTH = 375; private static final int MOBILE_ONLY_HEIGHT = 560; @@ -80,6 +97,8 @@ public class FormArea extends JComponent implements ScrollRulerComponent { // 初始时滑块值为100,托动后的值设为START_VALUE; private double START_VALUE = DEFAULT_SLIDER; private double screenValue; + private UIButton fixLayoutSwitchButton; + private boolean isFixLayoutEditState; public FormScrollBar getHorScrollBar() { @@ -116,10 +135,24 @@ public class FormArea extends JComponent implements ScrollRulerComponent { addFormRuler(); } this.setFocusTraversalKeysEnabled(false); - this.designer.addMouseWheelListener(showValSpinnerMouseWheelListener); + + + this.designer.addMouseWheelListener(new FormAreaMouseWheelHandler(this)); registerShortCutKey(); } + public FormScrollBar getVerticalScrollBar() { + return verScrollBar; + } + + public FormScrollBar getHorizontalScrollBar() { + return horScrollBar; + } + + public JFormSliderPane getSlidePane() { + return slidePane; + } + /** * 注册缩放快捷键 * mac: command + 和 command - @@ -153,16 +186,44 @@ public class FormArea extends JComponent implements ScrollRulerComponent { widthPane.setEnabled(!formMobileAttr.isMobileOnly()); } - MouseWheelListener showValSpinnerMouseWheelListener = new MouseWheelListener() { - @Override - public void mouseWheelMoved(MouseWheelEvent e) { - if (InputEventBaseOnOS.isControlDown(e)) { - int dir = e.getWheelRotation(); - int old_resolution = slidePane.getShowValue(); - slidePane.setShowValue(old_resolution - (dir * SHOWVALMIN)); + private UIButton createFixLayoutSwitchButton(){ + UIButton button = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_No_Fix_Layout")); + button.setIcon(IOUtils.readIcon("/com/fr/base/images/share/filter_combo.png")); + button.setName(FIX_LAYOUT_SWITCH_BUTTON); + button.setUI(new UIButtonUI(){ + @Override + protected void paintBorder(Graphics g, UIButton b) { + } - } - }; + protected void doExtraPainting(UIButton b, Graphics2D g2d, int w, int h, String selectedRoles) { + if (isPressed(b) && b.isPressedPainted()) { + GUIPaintUtils.fillPressed(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles)); + } else if (isRollOver(b)) { + GUIPaintUtils.fillRollOver(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted()); + } + } + }); + button.setHorizontalTextPosition(SwingConstants.LEFT); + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setPreferredSize(new Dimension(180, 59)); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new PopupMenuItem(new Switch2NoFixLayoutAction())); + popupMenu.add(new PopupMenuItem(new Switch2FixLayoutAction())); + button.setComponentPopupMenu(popupMenu); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + GUICoreUtils.showPopupMenu(popupMenu, fixLayoutSwitchButton, 0, -59); + } + }); + button.setVisible(!isAbsoluteBodyLayout()); + return button; + } + + private boolean isAbsoluteBodyLayout() { + return ((WFitLayout) designer.getRootComponent().toData()).getBodyLayoutType() == WBodyLayoutType.ABSOLUTE; + } @@ -175,6 +236,11 @@ public class FormArea extends JComponent implements ScrollRulerComponent { double[] rowSize = {f}; double[] columnSize = {p, f, p, p, p, p, p, f, p}; UILabel tipsPane = new UILabel("form"); + fixLayoutSwitchButton = createFixLayoutSwitchButton(); + JPanel layoutSwitchPane = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); + layoutSwitchPane.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0)); + layoutSwitchPane.add(fixLayoutSwitchButton); + widthPane = new UINumberField(); widthPane.setPreferredSize(new Dimension(60, 0)); heightPane = new UINumberField(); @@ -183,7 +249,7 @@ public class FormArea extends JComponent implements ScrollRulerComponent { slidePane = JFormSliderPane.getInstance(); JPanel resizePane = TableLayoutHelper.createCommonTableLayoutPane( - new JComponent[][]{{tipsPane, new UILabel(), widthPane, + new JComponent[][]{{tipsPane, layoutSwitchPane, widthPane, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Indent_Pixel")), new UILabel("x"), heightPane, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Indent_Pixel")), @@ -198,6 +264,25 @@ public class FormArea extends JComponent implements ScrollRulerComponent { slidePane.addValueChangeListener(showValSpinnerChangeListener); } + public void undoFixLayoutState(boolean isFixLayout) { + getFormEditor().getRootComponent().setFixLayout(isFixLayout); + this.switchLayout(isFixLayout); + } + + public void switchBodyLayout(XLayoutContainer xLayoutContainer) { + this.fixLayoutSwitchButton.setVisible(xLayoutContainer.supportFixLayout()); + this.switchLayout(false); + } + + private void switchLayout(boolean isFixLayout) { + this.isFixLayoutEditState = isFixLayout; + this.fixLayoutSwitchButton.setText(isFixLayout ? com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Fix_Layout") : + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_No_Fix_Layout")); + FormMobileAttr formMobileAttr = designer.getTarget().getFormMobileAttr(); + widthPane.setEnabled(!isFixLayout && !formMobileAttr.isMobileOnly()); + heightPane.setEnabled(!isFixLayout); + } + private void setWidgetsConfig() { widthPane.setHorizontalAlignment(widthPane.CENTER); @@ -281,8 +366,7 @@ public class FormArea extends JComponent implements ScrollRulerComponent { if(object instanceof XCreator){ updateCreatorsBackupBound((XCreator) object); } - } - } + } } //设置宽度的控件及响应事件 @@ -817,7 +901,7 @@ public class FormArea extends JComponent implements ScrollRulerComponent { } this.slidePane.setShowValue((int) slide); - } + } /** @@ -899,4 +983,43 @@ public class FormArea extends JComponent implements ScrollRulerComponent { } + public boolean isFixLayout(){ + return this.isFixLayoutEditState; + } + + class Switch2NoFixLayoutAction extends UpdateAction{ + public Switch2NoFixLayoutAction(){ + this.putValue(Action.SMALL_ICON, null); + this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_No_Fix_Layout")); + this.setSmallIcon("/com/fr/design/form/images/no_fix_layout_icon.png"); + } + + @Override + public void actionPerformed(ActionEvent e) { + getFormEditor().getRootComponent().setFixLayout(false); + switchLayout(false); + designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED); + DesignerContext.getDesignerFrame().refresh(); + } + } + + class Switch2FixLayoutAction extends UpdateAction{ + + public Switch2FixLayoutAction(){ + this.putValue(Action.SMALL_ICON, null); + this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Fix_Layout")); + this.setSmallIcon("/com/fr/design/form/images/fix_layout_icon.png"); + } + + @Override + public void actionPerformed(ActionEvent e) { + getFormEditor().getRootComponent().setFixLayout(true); + switchLayout(true); + designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED); + DesignerContext.getDesignerFrame().refresh(); + } + } + + + } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormAreaMouseWheelHandler.java b/designer-form/src/main/java/com/fr/design/mainframe/FormAreaMouseWheelHandler.java new file mode 100644 index 000000000..6c4095a45 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormAreaMouseWheelHandler.java @@ -0,0 +1,75 @@ +package com.fr.design.mainframe; + +import com.fr.common.inputevent.InputEventBaseOnOS; + +import javax.swing.JScrollBar; +import javax.swing.JViewport; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/24 + */ +public class FormAreaMouseWheelHandler implements MouseWheelListener { + private final DesignerTranslateMouseWheelHandler translateMouseWheelHandler; + private final DesignerScaleMouseWheelHandler scaleMouseWheelHandler; + + public FormAreaMouseWheelHandler(FormArea formArea) { + translateMouseWheelHandler = new DesignerTranslateMouseWheelHandler(new FormAreaScrollPaneAdapter(formArea)); + scaleMouseWheelHandler = new DesignerScaleMouseWheelHandler(new FormAreaScalePaneAdapter(formArea), FormArea.SHOWVALMIN); + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if (InputEventBaseOnOS.isControlDown(e)) { + scaleMouseWheelHandler.mouseWheelMoved(e); + } else { + translateMouseWheelHandler.mouseWheelMoved(e); + } + } + + private static class FormAreaScalePaneAdapter implements DesignerScaleMouseWheelHandler.ScalePane { + private final FormArea formArea; + + public FormAreaScalePaneAdapter(FormArea formArea) { + this.formArea = formArea; + } + + @Override + public JFormSliderPane getSlidePane() { + return formArea.getSlidePane(); + } + } + + private static class FormAreaScrollPaneAdapter implements DesignerTranslateMouseWheelHandler.ScrollPane { + private final FormArea formArea; + private final JViewport viewport; + + public FormAreaScrollPaneAdapter(FormArea formArea) { + this.formArea = formArea; + this.viewport = new JViewport(); + } + + @Override + public boolean isWheelScrollingEnabled() { + return true; + } + + @Override + public JScrollBar getVerticalScrollBar() { + return formArea.getVerticalScrollBar(); + } + + @Override + public JScrollBar getHorizontalScrollBar() { + return formArea.getHorizontalScrollBar(); + } + + @Override + public JViewport getViewport() { + return this.viewport; + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java index 7db972e9b..af4d2ae2d 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java @@ -79,7 +79,7 @@ public class FormCreatorDropTarget extends DropTarget { this.tabDragInner = new TabDragInner(designer); } - private void adding(int x, int y) { + public void adding(int x, int y) { // 当前鼠标所在的组件 XCreator hoveredComponent = designer.getComponentAt(x, y); // 获取该组件所在的焦点容器 @@ -193,7 +193,6 @@ public class FormCreatorDropTarget extends DropTarget { private void dealWithContainer(int x, int y, XLayoutContainer container) { HoverPainter painter = null; - if (container != current || designer.getPainter() == null) { // 如果焦点容器不是当前容器 if (current != null) { @@ -204,15 +203,9 @@ public class FormCreatorDropTarget extends DropTarget { throw new IllegalArgumentException("container can not be null!"); } //获取painter的时候要考虑布局之间嵌套的问题 - XLayoutContainer xLayoutContainer = container.getTopLayout(); - if (xLayoutContainer != null && xLayoutContainer.getParent() != null - && ((XLayoutContainer) xLayoutContainer.getParent()).acceptType(XWAbsoluteLayout.class)) { - if (!xLayoutContainer.isEditable()) { - xLayoutContainer = (XLayoutContainer) xLayoutContainer.getParent(); - } - } + XLayoutContainer xLayoutContainer = XCreatorUtils.getTopEditableContainer(container); painter = AdapterBus.getContainerPainter(designer, - xLayoutContainer != null && xLayoutContainer.acceptType(XWAbsoluteLayout.class) ? xLayoutContainer : container); + xLayoutContainer != null ? xLayoutContainer : container); // 为界面设计器设置提示渲染提示器 designer.setPainter(painter); @@ -227,8 +220,9 @@ public class FormCreatorDropTarget extends DropTarget { } } if (painter != null) { + XLayoutContainer xLayoutContainer = XCreatorUtils.getTopEditableContainer(container); // 为提示渲染器设置焦点位置、区域等渲染参数 - Rectangle rect = ComponentUtils.getRelativeBounds(container); + Rectangle rect = ComponentUtils.getRelativeBounds(xLayoutContainer != null ? xLayoutContainer : container); rect.x -= designer.getArea().getHorizontalValue(); rect.y -= designer.getArea().getVerticalValue(); painter.setRenderingBounds(rect); @@ -236,7 +230,7 @@ public class FormCreatorDropTarget extends DropTarget { painter.setCreator(addingModel.getXCreator()); } } - + private void promptUser(int x, int y, XLayoutContainer container) { if (!addingModel.getXCreator().canEnterIntoParaPane() && container.acceptType(XWParameterLayout.class)) { promptButton.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Forbid_Drag_Into_Para_Pane")); @@ -288,6 +282,7 @@ public class FormCreatorDropTarget extends DropTarget { int y = designer.getRelativeY(loc.y); hovering(x, y); tabDragInner.canDragIn(designer.getComponentAt(x, y), x, y); + designer.draggingComponent(x, y); } /** diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java b/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java index cbe9e87e6..3eb40b6a2 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java @@ -1,10 +1,6 @@ package com.fr.design.mainframe; import com.fr.base.Parameter; -import com.fr.base.ScreenResolution; -import com.fr.base.theme.FormTheme; -import com.fr.base.theme.TemplateTheme; -import com.fr.base.theme.TemplateThemeCompatible; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignModelAdapter; import com.fr.design.DesignState; @@ -22,7 +18,9 @@ import com.fr.design.designer.beans.actions.MoveToBottomAction; import com.fr.design.designer.beans.actions.MoveToTopAction; import com.fr.design.designer.beans.actions.MoveUpAction; import com.fr.design.designer.beans.actions.PasteAction; +import com.fr.design.designer.beans.adapters.layout.DefaultDesignerBaseOperate; import com.fr.design.designer.beans.adapters.layout.FRParameterLayoutAdapter; +import com.fr.design.designer.beans.adapters.layout.DesignerBaseOperate; import com.fr.design.designer.beans.events.CreatorEventListenerTable; import com.fr.design.designer.beans.events.DesignerEditListener; import com.fr.design.designer.beans.events.DesignerEvent; @@ -44,7 +42,6 @@ import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; import com.fr.design.designer.properties.FormWidgetAuthorityEditPane; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.event.DesignerOpenedListener; -import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.fit.DesignerUIModeConfig; import com.fr.design.form.util.XCreatorConstants; @@ -61,9 +58,7 @@ import com.fr.design.utils.gui.LayoutUtils; import com.fr.form.FormElementCaseContainerProvider; import com.fr.form.FormElementCaseProvider; import com.fr.form.main.Form; -import com.fr.form.main.WidgetGather; import com.fr.form.parameter.FormSubmitButton; -import com.fr.form.ui.AbstractBorderStyleWidget; import com.fr.form.ui.EditorHolder; import com.fr.form.ui.PaddingMargin; import com.fr.form.ui.Widget; @@ -160,6 +155,7 @@ public class FormDesigner extends TargetComponent
implements TreeSelection // 编辑状态的事件表 private CreatorEventListenerTable edit; protected List designerActions; + protected List basicActions; private FormDesignerModeForSpecial desigerMode; private Action switchAction; private FormElementCaseContainerProvider elementCaseContainer; @@ -227,7 +223,7 @@ public class FormDesigner extends TargetComponent implements TreeSelection public Parameter[] getNoRepeatParas(Parameter[] paras) { List paraList = new ArrayList(); - java.util.Set set = new java.util.HashSet(); + Set set = new java.util.HashSet(); for (Parameter p : paras) { if (!set.contains(p.getName().toLowerCase())) { paraList.add(p); @@ -252,7 +248,7 @@ public class FormDesigner extends TargetComponent implements TreeSelection public void refreshParameter() { XLayoutContainer rootContainer = this.getParaComponent(); if (rootContainer != null) { - java.util.List namelist = new ArrayList(); + List namelist = new ArrayList(); rootContainer.getAllXCreatorNameList(rootContainer, namelist); // parameterArray是报表的所有参数, nameList是已经在参数面板添加过控件的参数名 // 与已有的参数列表比较 如果已经存在 就除去 @@ -1014,15 +1010,6 @@ public class FormDesigner extends TargetComponent implements TreeSelection } private void refreshCenter(Widget centerWidget, XLayoutContainer formLayoutContainer) { - // 不存在center块, 说明是新建的模板 - if (centerWidget == null) { - XLayoutContainer layoutContainer = (XLayoutContainer) XCreatorUtils.createXCreator(new WFitLayout("body")); - layoutContainer.setSize(LARGE_PREFERRED_SIZE); - setRootComponent(layoutContainer); - formLayoutContainer.add(rootComponent, WBorderLayout.CENTER); - return; - } - XLayoutContainer centerContainer = (XLayoutContainer) XCreatorUtils.createXCreator(centerWidget); Dimension d = new Dimension(); d.width = ((WFitLayout) centerWidget).getContainerWidth(); @@ -1124,6 +1111,10 @@ public class FormDesigner extends TargetComponent implements TreeSelection return addingModel; } + public void setAddingModel(AddingModel addingModel) { + this.addingModel = addingModel; + } + public XCreator getComponentAt(MouseEvent e) { return getComponentAt(e.getX(), e.getY()); } @@ -1214,20 +1205,28 @@ public class FormDesigner extends TargetComponent implements TreeSelection public void startDraggingComponent(XCreator xCreator, MouseEvent lastPressEvent, int x, int y) { // 根据所选择的组件的BeanInfo生成相应的AddingModel // AddingModel和StateModel不一样,适合当前选择的组件相关的 - int creatorWidth = xCreator.getWidth(); - int creatorHeight = xCreator.getHeight(); this.addingModel = new AddingModel(xCreator, x, y); TransferHandler handler = new DesignerTransferHandler(this, addingModel); setTransferHandler(handler); handler.exportAsDrag(this, lastPressEvent, TransferHandler.COPY); - XCreator parent = XCreatorUtils.getParentXLayoutContainer(xCreator); - selectionModel.removeCreator(xCreator, creatorWidth, creatorHeight); - selectionModel.setSelectedCreator(parent); + XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(xCreator); + parent.getLayoutAdapter().dragStart(xCreator, selectionModel); this.setDropTarget(new FormCreatorDropTarget(this)); // 触发状态添加模式事件 repaint(); } + public void draggingComponent(int x, int y){ + XCreator xCreator = this.addingModel.getXCreator(); + XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(xCreator); + if (parent!= null && parent.getLayoutAdapter()!=null){ + parent.getLayoutAdapter().dragOver(xCreator, selectionModel, x, y); + } + + // 触发状态添加模式事件 + repaint(); + } + /** * 改变组件值 * @@ -1313,9 +1312,6 @@ public class FormDesigner extends TargetComponent implements TreeSelection protected void setToolbarButtons() { - //自适应布局和底层都不能删除 - DesignerContext.getDesignerFrame().checkCombineUp(!isRootSelected(), NAME_ARRAY_LIST); - if (isParameterSelected()) { DesignerContext.getDesignerFrame().checkCombineUp(false, PARAMETER_TOOLAR_BAN_LIST); } @@ -1378,14 +1374,37 @@ public class FormDesigner extends TargetComponent implements TreeSelection */ public UpdateAction[] getActions() { if (designerActions == null) { - designerActions = new ArrayList(Arrays.asList(new UpdateAction[]{new CutAction(this), new CopyAction(this), new PasteAction(this), - new FormDeleteAction(this), new MoveToTopAction(this), new MoveToBottomAction(this), - new MoveUpAction(this), new MoveDownAction(this)})); + designerActions = new ArrayList(getBasicActions()); + designerActions.add(new MoveToTopAction(this)); + designerActions.add(new MoveToBottomAction(this)); + designerActions.add(new MoveUpAction(this)); + designerActions.add(new MoveDownAction(this)); dmlActions(designerActions); } return designerActions.toArray(new UpdateAction[designerActions.size()]); } + private List getBasicActions(){ + if (basicActions == null) { + basicActions = new ArrayList(); + basicActions.add(new CutAction(this)); + basicActions.add(new CopyAction(this)); + basicActions.add(new PasteAction(this)); + basicActions.add(new FormDeleteAction(this)); + } + return basicActions; + } + + public JComponent[] getBasicActionComponent() { + List actions = getBasicActions(); + int size = actions.size(); + JComponent[] jComponents = new JComponent[size]; + for (int i = 0; i < size; i++) { + jComponents[i] = actions.get(i).createToolBarComponentByName("Global_Toolbar"); + } + return jComponents; + } + /** * 扩展菜单项 * @@ -1404,16 +1423,34 @@ public class FormDesigner extends TargetComponent implements TreeSelection } } + private DesignerBaseOperate getLayoutBaseOperate(){ + FormSelection selection = this.getSelectionModel().getSelection(); + XCreator creator = selection.getSelectedCreator(); + XLayoutContainer container = (XLayoutContainer) creator.getParent(); + if (container == null) { + return new DefaultDesignerBaseOperate(); + } + return container.getLayoutAdapter().getDesignerBaseOperate(); + } + public boolean isCurrentComponentCutable() { - return !(isRootSelected() || isParameterSelected()); + DesignerBaseOperate designerBaseOperate = getLayoutBaseOperate(); + return !(isRootSelected() || isParameterSelected()) && designerBaseOperate.supportCutAction(); } public boolean isCurrentComponentCopyable() { - return !(isRootSelected() || isParameterSelected()); + DesignerBaseOperate designerBaseOperate = getLayoutBaseOperate(); + return !(isRootSelected() || isParameterSelected()) && designerBaseOperate.supportCopyAction(); } public boolean isCurrentComponentDeletable() { - return !isRootSelected(); + DesignerBaseOperate designerBaseOperate = getLayoutBaseOperate(); + return !isRootSelected() && designerBaseOperate.supportDeleteAction(); + } + + public boolean isCurrentComponentPastable() { + DesignerBaseOperate designerBaseOperate = getLayoutBaseOperate(); + return designerBaseOperate.supportPasteAction(); } // 当前选中控件可以上移一层吗? @@ -1469,6 +1506,10 @@ public class FormDesigner extends TargetComponent implements TreeSelection return formArea; } + public void switchBodyLayout(XLayoutContainer xLayoutContainer){ + formArea.switchBodyLayout(xLayoutContainer); + } + /** * 设置上层区域 * diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java b/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java index 776925044..db5367ee9 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java @@ -210,10 +210,10 @@ public class FormDesignerUI extends ComponentUI { } XCreator bean = addingModel.getXCreator(); int x = addingModel.getCurrentX(); - int y = addingModel.getCurrentY(); + int y = addingModel.getCurrentY() ; - int width = bean.getWidth(); - int height = bean.getHeight(); + int width = bean.initEditorSize().width; + int height = bean.initEditorSize().height; Graphics clipg = g.create(x, y, width, height); ArrayList dbcomponents = new ArrayList(); // 禁止双缓冲行为 diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormUndoState.java b/designer-form/src/main/java/com/fr/design/mainframe/FormUndoState.java index e4fb5b755..8a579b8d1 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormUndoState.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormUndoState.java @@ -14,6 +14,7 @@ public class FormUndoState extends BaseUndoState { private double widthValue; private double heightValue; private double slideValue; + private boolean isFixLayout; public FormUndoState(BaseJForm t, FormArea formArea) { super(t); @@ -31,6 +32,7 @@ public class FormUndoState extends BaseUndoState { this.widthValue = formArea.getWidthPaneValue(); this.heightValue = formArea.getHeightPaneValue(); this.slideValue = formArea.getSlideValue(); + this.isFixLayout = formArea.isFixLayout(); } /** @@ -89,6 +91,14 @@ public class FormUndoState extends BaseUndoState { return this.slideValue; } + /** + * 返回是否处于固定布局编辑状态下 + * @return + */ + public boolean isFixLayout(){ + return isFixLayout; + } + @Override public void applyState() { this.getApplyTarget().applyUndoState4Form(this); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java index d792f0eca..f2268c86c 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java @@ -36,6 +36,7 @@ public class FormWidgetDetailPane extends FormDockView{ private JPanel centerPane; private UIHeadGroup headGroup; private List paneList; + private CardLayout cardLayout; private boolean isEmptyPane = false; @@ -86,7 +87,7 @@ public class FormWidgetDetailPane extends FormDockView{ initPaneList(); this.setBorder(null); - final CardLayout cardLayout = new CardLayout(); + cardLayout = new CardLayout(); centerPane = new JPanel(cardLayout); String[] paneNames = new String[paneList.size()]; for (int i = 0; i < paneList.size(); i++) { @@ -137,6 +138,14 @@ public class FormWidgetDetailPane extends FormDockView{ this.add(panel, BorderLayout.CENTER); } + public void switch2Local() { + cardLayout.show(centerPane, paneList.get(0).getTitle()); + } + + public void swich2Online() { + cardLayout.show(centerPane, paneList.get(1).getTitle()); + } + private UILabel tipLabel(String text) { UILabel tipLabel = new UILabel(text); tipLabel.setHorizontalAlignment(SwingConstants.CENTER); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java index 955c9c2ef..bc0c75b30 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java @@ -6,12 +6,12 @@ import com.fr.base.Parameter; import com.fr.base.Releasable; import com.fr.base.extension.FileExtension; import com.fr.base.iofile.attr.ExtendSharableAttrMark; -import com.fr.base.theme.TemplateThemeCompatible; -import com.fr.base.vcs.DesignerMode; import com.fr.base.theme.FormTheme; import com.fr.base.theme.FormThemeConfig; import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeCompatible; import com.fr.base.theme.TemplateThemeConfig; +import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignModelAdapter; import com.fr.design.DesignState; import com.fr.design.ExtraDesignClassManager; @@ -23,10 +23,6 @@ import com.fr.design.base.mode.DesignModeContext; import com.fr.design.cell.FloatElementsProvider; import com.fr.design.data.datapane.TableDataTreePane; import com.fr.design.designer.TargetComponent; -import com.fr.design.designer.beans.actions.CopyAction; -import com.fr.design.designer.beans.actions.CutAction; -import com.fr.design.designer.beans.actions.FormDeleteAction; -import com.fr.design.designer.beans.actions.PasteAction; import com.fr.design.designer.beans.events.DesignerEditListener; import com.fr.design.designer.beans.events.DesignerEvent; import com.fr.design.designer.creator.XComponent; @@ -140,7 +136,11 @@ public class JForm extends JTemplate implements BaseJForm implements BaseJForm dialog = new TemplateThemeUsingDialog<>(designerFrame, JForm.this, FormThemeConfig.getInstance()); + TemplateThemeUsingDialog dialog = new TemplateThemeUsingDialog(); dialog.setVisible(true); } }); @@ -672,6 +671,7 @@ public class JForm extends JTemplate implements BaseJForm implements BaseJForm implements BaseJForm dbcomponents = new ArrayList(); // 禁止双缓冲 ComponentUtils.disableBuffer(creator, dbcomponents); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java index 96b321c93..1b36f08d1 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java @@ -1,6 +1,7 @@ package com.fr.design.mainframe.share; -import com.fr.design.mainframe.share.ui.base.PopupPreviewPane; +import com.fr.design.mainframe.share.ui.base.AbstractWidgetPopupPreviewPane; +import com.fr.design.mainframe.share.ui.base.LocalWidgetPopupPreviewPane; import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.ComparatorUtils; @@ -13,16 +14,16 @@ import java.awt.Container; * @Author: Yuan.Wang * @Date: 2021/1/15 */ -public abstract class AbstractWidgetSelectPane extends JPanel { +public abstract class AbstractWidgetSelectPane extends JPanel { private static final int SCROLL_BAR_HEIGHT = 10; - private final PopupPreviewPane previewPane; + private final AbstractWidgetPopupPreviewPane previewPane; private String currentShowWidgetID; public AbstractWidgetSelectPane() { - this.previewPane = new PopupPreviewPane(); + this.previewPane = createPopupPreviewPane(); } - public void showPreviewPane(PreviewWidgetBlock comp, String showWidgetID) { + public void showPreviewPane(PreviewWidgetBlock comp, String showWidgetID) { if (ComparatorUtils.equals(currentShowWidgetID, showWidgetID)) { return; } @@ -36,7 +37,7 @@ public abstract class AbstractWidgetSelectPane extends JPanel { this.currentShowWidgetID = StringUtils.EMPTY; } - private void popupPreviewPane(PreviewWidgetBlock comp, String showWidgetID) { + private void popupPreviewPane(PreviewWidgetBlock comp, String showWidgetID) { if (previewPane.isVisible()) { previewPane.setVisible(false); } @@ -44,7 +45,7 @@ public abstract class AbstractWidgetSelectPane extends JPanel { if (!previewPane.isVisible() && comp.getWidth() != 0 && comp.getHeight() != 0) { //父容器是GroupPane,要获得的是GroupPane的父容器 Container parentContainer =getParentContainer(); - previewPane.setComp(comp.getPreviewImage()); + previewPane.populateBean(comp); int popupPosY = comp.getLocationOnScreen().y - parentContainer.getLocationOnScreen().y; if (previewPane.getHeight() + popupPosY > parentContainer.getHeight() + SCROLL_BAR_HEIGHT) { popupPosY -= (previewPane.getHeight() + popupPosY - parentContainer.getHeight() - SCROLL_BAR_HEIGHT); @@ -58,5 +59,7 @@ public abstract class AbstractWidgetSelectPane extends JPanel { } } + protected abstract AbstractWidgetPopupPreviewPane createPopupPreviewPane(); + abstract protected Container getParentContainer(); } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java index 126660665..ed1c2a91d 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java @@ -4,6 +4,7 @@ import com.fr.base.TableData; import com.fr.base.iofile.attr.ExtendSharableAttrMark; import com.fr.base.iofile.attr.SharableAttrMark; import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.share.generate.impl.AbstractComponentCreatorProcessor; @@ -18,6 +19,7 @@ import com.fr.form.share.utils.ShareUtils; import com.fr.form.ui.AbstractBorderStyleWidget; import com.fr.form.ui.Widget; import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; import com.fr.stable.fun.IOFileAttrMark; import com.fr.workspace.WorkContext; import org.jetbrains.annotations.NotNull; @@ -61,8 +63,13 @@ public class ComponentCreator extends AbstractComponentCreatorProcessor { private void setSuitableTemplateThemeName(JTemplate jt, DefaultSharableWidget info) { TemplateTheme theme = jt.getTemplateTheme(); - if (theme != null) { - info.setSuitableTemplateThemeName(theme.getName()); + if (theme != null ) { + String name = theme.getName(); + TemplateThemeConfig config = jt.getUsingTemplateThemeConfig(); + String name4LegacyTemplate = config.getThemeName4LegacyTemplate(); + if (!StringUtils.equals(name, name4LegacyTemplate)) { + info.setSuitableTemplateThemeName(name); + } } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/DownloadSuitableThemeAction.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/DownloadSuitableThemeAction.java new file mode 100644 index 000000000..8eb068fd6 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/DownloadSuitableThemeAction.java @@ -0,0 +1,186 @@ +package com.fr.design.mainframe.share.ui.actions; + +import com.fr.base.theme.FormTheme; +import com.fr.base.theme.FormThemeConfig; +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; +import com.fr.design.DesignerEnvManager; +import com.fr.design.actions.UpdateAction; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.i18n.Toolkit; +import com.fr.design.login.DesignerLoginHelper; +import com.fr.design.login.DesignerLoginSource; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.share.util.DownloadUtils; +import com.fr.design.mainframe.theme.dialog.TemplateThemeUsingDialog; +import com.fr.stable.StringUtils; +import com.fr.transaction.CallBackAdaptor; +import com.fr.workspace.WorkContext; + +import javax.swing.Action; +import javax.swing.JOptionPane; +import javax.swing.SwingWorker; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.concurrent.ExecutionException; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/28 + */ +public class DownloadSuitableThemeAction extends UpdateAction { + private final String themePath; + private boolean downloading = false; + private JTemplate currentTemplate; + + public DownloadSuitableThemeAction(String themePath) { + this.themePath = themePath; + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Download_Suitable_Theme")); + } + + @Override + public void actionPerformed(ActionEvent e) { + currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + fetchTheme(); + } + + private boolean checkAuthority() { + if (!WorkContext.getCurrent().isRoot()) { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Share_Download_Suitable_Theme_No_Authority_Tip_Message"), + Toolkit.i18nText("Fine-Design_Share_Download_Suitable_Theme_No_Authority_Tip_Title"), + JOptionPane.WARNING_MESSAGE); + return false; + } + + String userName = DesignerEnvManager.getEnvManager().getDesignerLoginUsername(); + if (StringUtils.isEmpty(userName)) { + DesignerLoginHelper.showLoginDialog(DesignerLoginSource.NORMAL); + return false; + } + + return true; + } + + private void fetchTheme() { + if (!checkAuthority()) { + onThemeFetched(null); + return; + } + if (downloading) { + return; + } + downloading = true; + + new SwingWorker() { + + @Override + protected FormTheme doInBackground() { + return DownloadUtils.downloadThemeFile(themePath); + } + + @Override + protected void done() { + FormTheme theme = null; + try { + theme = get(); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + + onThemeFetched(theme); + downloading = false; + } + }.execute(); + } + + public void onThemeFetched(FormTheme theme) { + if (theme == null) { + return; + } + saveTheme(theme); + } + + private FormTheme ensureThemeHasUniqueName(FormTheme theme, String expectedName) { + if (!FormThemeConfig.getInstance().contains(expectedName)) { + theme.setName(expectedName); + return theme; + } else { + String newName = (String) FineJOptionPane.showInputDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Share_Rename_Suitable_Theme_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Rename"), + FineJOptionPane.QUESTION_MESSAGE, null, null, + expectedName); + + return StringUtils.isEmpty(newName) ? null : ensureThemeHasUniqueName(theme, newName); + } + } + + private void saveTheme(FormTheme theme) { + final FormTheme uniqueNamedTheme = ensureThemeHasUniqueName(theme, theme.getName()); + if (uniqueNamedTheme != null) { + FormThemeConfig.getInstance().addTheme(theme, true, new CallBackAdaptor() { + @Override + public void afterCommit() { + super.afterCommit(); + onThemeSaved(uniqueNamedTheme); + } + + @Override + public void afterRollback() { + super.afterRollback(); + onThemeSaved(null); + } + }); + } else { + onThemeSaved(null); + } + } + + public void onThemeSaved(FormTheme theme) { + if (theme == null) { + return; + } + + TemplateThemeUsingDialog dialog = new TemplateThemeUsingDialog(); + dialog.addWindowListener(new UsingDialogAdapter(theme)); + dialog.setVisible(true); + } + + public void applyTheme(JTemplate template, final String name, Window dialog) { + TemplateThemeConfig config = template.getUsingTemplateThemeConfig(); + TemplateTheme theme = config.cachedFetch(name); + template.setTemplateTheme(theme); + dialog.repaint(); + } + + private class UsingDialogAdapter extends WindowAdapter { + private final FormTheme theme; + + public UsingDialogAdapter(FormTheme theme) { + this.theme = theme; + } + + @Override + public void windowOpened(WindowEvent e) { + super.windowOpened(e); + Window window = e.getWindow(); + int returnVal = FineJOptionPane.showConfirmDialog( + window, + Toolkit.i18nText("Fine-Design_Share_Apply_Suitable_Theme_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Confirm"), + FineJOptionPane.OK_CANCEL_OPTION); + if (returnVal == JOptionPane.YES_OPTION) { + applyTheme(currentTemplate, theme.getName(), window); + } + window.removeWindowListener(this); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/Jump2DetailAction.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/Jump2DetailAction.java new file mode 100644 index 000000000..73a91fc87 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/Jump2DetailAction.java @@ -0,0 +1,41 @@ +package com.fr.design.mainframe.share.ui.actions; + +import com.fr.design.actions.UpdateAction; +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.stable.StringUtils; + +import javax.swing.Action; +import java.awt.Desktop; +import java.awt.event.ActionEvent; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/28 + */ +public class Jump2DetailAction extends UpdateAction { + private static final String ONLINE_WIDGET_DETAIL_FORMATTED_URL = "https://market.fanruan.com/reuse/%s"; + private final String id; + + public Jump2DetailAction(String id) { + this.id = id; + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Jump_To_Detail")); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (StringUtils.isNotEmpty(id)) { + Desktop desktop = Desktop.getDesktop(); + try { + desktop.browse(new URI(String.format(ONLINE_WIDGET_DETAIL_FORMATTED_URL, id))); + } catch (IOException | URISyntaxException ioException) { + ioException.printStackTrace(); + } + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/AbstractWidgetPopupPreviewPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/AbstractWidgetPopupPreviewPane.java new file mode 100644 index 000000000..12c2c33ff --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/AbstractWidgetPopupPreviewPane.java @@ -0,0 +1,15 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; + +import javax.swing.JPopupMenu; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/15 + */ +public abstract class AbstractWidgetPopupPreviewPane extends JPopupMenu { + + public abstract void populateBean(PreviewWidgetBlock block); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupPreviewPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LocalWidgetPopupPreviewPane.java similarity index 81% rename from designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupPreviewPane.java rename to designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LocalWidgetPopupPreviewPane.java index 91b1eae89..f78dbf701 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupPreviewPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LocalWidgetPopupPreviewPane.java @@ -1,6 +1,9 @@ package com.fr.design.mainframe.share.ui.base; import com.fr.design.constants.UIConstants; +import com.fr.design.mainframe.share.ui.block.LocalWidgetBlock; +import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; +import com.fr.form.share.DefaultSharableWidget; import com.fr.general.IOUtils; import javax.swing.BorderFactory; @@ -17,17 +20,16 @@ import java.awt.Toolkit; /** * Created by kerry on 2020-06-23 */ -public class PopupPreviewPane extends JPopupMenu { - private Container contentPane; +public class LocalWidgetPopupPreviewPane extends AbstractWidgetPopupPreviewPane { private Image compImage; private static final int WIDTH = 400; private static final int STANDARD_DPI = 128; private static final int MAX_HEIGHT = 400; private static final int HEIGHT = 210; - public PopupPreviewPane() { + public LocalWidgetPopupPreviewPane() { setFocusable(false); - contentPane = new JPanel(); + Container contentPane = new JPanel(); contentPane.setBackground(Color.white); this.setLayout(new BorderLayout()); this.add(contentPane, BorderLayout.CENTER); @@ -36,9 +38,9 @@ public class PopupPreviewPane extends JPopupMenu { setBorder(BorderFactory.createLineBorder(UIConstants.LINE_COLOR)); } - public void setComp(Image compImage) { + public void populateBean(PreviewWidgetBlock block) { try { - this.compImage = compImage; + this.compImage = block.getPreviewImage(); this.updateSize(); } catch (Exception e) { e.printStackTrace(); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java index 06e513b80..54a813c43 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java @@ -1,20 +1,28 @@ package com.fr.design.mainframe.share.ui.block; +import com.fr.design.constants.UIConstants; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.mainframe.share.ui.actions.DownloadSuitableThemeAction; +import com.fr.design.mainframe.share.ui.actions.Jump2DetailAction; import com.fr.design.mainframe.share.ui.online.OnlineResourceManager; import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; import com.fr.design.mainframe.share.ui.online.ResourceLoader; +import com.fr.design.utils.gui.GUICoreUtils; import com.fr.form.share.bean.OnlineShareWidget; import com.fr.form.share.constants.ShareComponentConstants; import com.fr.log.FineLoggerFactory; import com.fr.stable.EncodeConstants; +import com.fr.stable.StringUtils; import com.fr.third.springframework.web.util.UriUtils; import org.jetbrains.annotations.NotNull; import javax.imageio.ImageIO; import javax.swing.ImageIcon; +import javax.swing.JPopupMenu; import java.awt.Dimension; import java.awt.Image; +import java.awt.event.MouseEvent; import java.io.IOException; import java.net.URL; @@ -41,10 +49,12 @@ public abstract class AbstractOnlineWidgetBlock extends PreviewWidgetBlock super.mouseClicked(e); if (e.getButton() == MouseEvent.BUTTON3 && !isEdit) { this.parentPane.hidePreviewPane(); - UIPopupMenu popupMenu = new UIPopupMenu(); - popupMenu.setOnlyText(true); - popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); - popupMenu.add(new PopupMenuItem(new MoveGroupAction())); - popupMenu.add(new PopupMenuItem(new RemoveAction())); - GUICoreUtils.showPopupMenu(popupMenu, this, e.getX(), e.getY()); + JPopupMenu rightClickPopupMenu = getRightClickPopupMenu(); + GUICoreUtils.showPopupMenu(rightClickPopupMenu, this, e.getX(), e.getY()); } } @@ -195,30 +194,36 @@ public class LocalWidgetBlock extends PreviewWidgetBlock hidePreview(); ComponentCollector.getInstance().collectPopupJump(); Object source = e.getSource(); - Widget creatorSource; - String shareId; if (source instanceof LocalWidgetBlock) { LocalWidgetBlock no = (LocalWidgetBlock) e.getSource(); if (no == null) { return; } - shareId = no.getBindInfo().getId(); - creatorSource = getGroup().getElCaseEditorById(shareId); - if (creatorSource == null) { - ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Drag_Error_Info")); + XCreator xCreator= transformXCreator(no); + if (xCreator == null) { return; } - creatorSource.setWidgetID(UUID.randomUUID().toString()); - ((AbstractBorderStyleWidget) creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); - //tab布局WCardMainBorderLayout通过反射出来的大小是960*480 - String suitableTemplateThemeName = no.getWidget().getSuitableTemplateThemeName(); - XCreator xCreator = ShareComponentUtils.createThemedXCreator(creatorSource, suitableTemplateThemeName, shareId, no.getBindInfo()); WidgetToolBarPane.getTarget().startDraggingBean(xCreator); lastPressEvent = null; this.setBorder(null); } } + public XCreator transformXCreator(LocalWidgetBlock block) { + String shareId = block.getBindInfo().getId(); + Widget creatorSource = getGroup().getElCaseEditorById(shareId); + if (creatorSource == null) { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Drag_Error_Info")); + return null; + } + creatorSource.setWidgetID(UUID.randomUUID().toString()); + ((AbstractBorderStyleWidget) creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); + //tab布局WCardMainBorderLayout通过反射出来的大小是960*480 + String suitableTemplateThemeName = block.getWidget().getSuitableTemplateThemeName(); + XCreator xCreator = ShareComponentUtils.createThemedXCreator(creatorSource, suitableTemplateThemeName, shareId, block.getBindInfo()); + return xCreator; + } + @Override public void paint(Graphics g) { super.paint(g); @@ -265,6 +270,18 @@ public class LocalWidgetBlock extends PreviewWidgetBlock return !WidgetSelectedManager.getInstance().isSelectEmpty(); } + @Override + public JPopupMenu createRightClickPopupMenu() { + + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new PopupMenuItem(new MoveGroupAction())); + popupMenu.add(new PopupMenuItem(new RemoveAction())); + + return popupMenu; + } + private class MoveGroupAction extends UpdateAction { public MoveGroupAction() { this.putValue(Action.SMALL_ICON, null); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java index 8ad419b03..325e28afe 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java @@ -35,8 +35,11 @@ import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.SwingConstants; import javax.swing.SwingWorker; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; import java.awt.AlphaComposite; import java.awt.BorderLayout; import java.awt.Color; @@ -89,6 +92,28 @@ public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { return southPane; } + @Override + public JPopupMenu createRightClickPopupMenu() { + JPopupMenu popupMenu = super.createRightClickPopupMenu(); + popupMenu.addPopupMenuListener(new PopupMenuListener() { + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + OnlineWidgetBlock.this.repaint(); + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + OnlineWidgetBlock.this.repaint(); + } + + @Override + public void popupMenuCanceled(PopupMenuEvent e) { + OnlineWidgetBlock.this.repaint(); + } + }); + return popupMenu; + } + @Override public void mouseEntered(MouseEvent e) { super.mouseEntered(e); @@ -112,7 +137,8 @@ public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { @Override public void mouseClicked(MouseEvent e) { super.mouseClicked(e); - if (!checkWidgetInstalled() && getDownloadIconRec().contains(e.getX(), e.getY())) { + boolean isLeftClickDownloadIcon = e.getButton() != MouseEvent.BUTTON3 && getDownloadIconRec().contains(e.getX(), e.getY()); + if (!isRightClickPopupMenuVisible() && isLeftClickDownloadIcon && !checkWidgetInstalled()) { downLoadWidget(); } } @@ -269,7 +295,7 @@ public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { return; } //如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层 - if (isMouseEnter || downloading) { + if (!isRightClickPopupMenuVisible() && (isMouseEnter || downloading)) { Graphics2D g2d = (Graphics2D) g; Composite oldComposite = g2d.getComposite(); //画白色的编辑层 @@ -298,7 +324,6 @@ public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { } } - class WidgetDownloadProcess implements com.fr.design.extra.Process { @Override diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java index 4b8458594..c3965f0da 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java @@ -35,7 +35,7 @@ public class OnlineWidgetPackageBlock extends AbstractOnlineWidgetBlock { detailLabel.addMouseListener(new MouseClickListener() { @Override public void mouseClicked(MouseEvent e) { - parentPane.showWidgetDetailPane(widget.getId()); + parentPane.showWidgetDetailPane(widget); } }); southPane.add(detailLabel, BorderLayout.EAST); @@ -51,7 +51,6 @@ public class OnlineWidgetPackageBlock extends AbstractOnlineWidgetBlock { this.setPreferredSize(new Dimension(ShareComponentConstants.SHARE_PACKAGE_BLOCK_WIDTH, ShareComponentConstants.SHARE_PACKAGE_BLOCK_HEIGHT)); this.add(createSouthPane(widget, parentPane), BorderLayout.SOUTH); } - } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java index 8ad9e2b11..58dee8945 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.ImageIcon; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; @@ -25,12 +26,14 @@ import java.io.Serializable; public abstract class PreviewWidgetBlock extends JPanel implements MouseListener, MouseMotionListener, Serializable { protected T widget; private boolean showing = false; + private final JPopupMenu rightClickPopupMenu; public PreviewWidgetBlock(T widget) { this.widget = widget; initPane(); this.addMouseListener(this); this.addMouseMotionListener(this); + rightClickPopupMenu = this.createRightClickPopupMenu(); } protected void initPane() { @@ -51,6 +54,18 @@ public abstract class PreviewWidgetBlock extends JPanel implements MouseListe return widget; } + protected JPopupMenu createRightClickPopupMenu() { + return null; + } + + protected JPopupMenu getRightClickPopupMenu() { + return rightClickPopupMenu; + } + + protected boolean isRightClickPopupMenuVisible() { + return rightClickPopupMenu != null && rightClickPopupMenu.isVisible(); + } + @NotNull protected abstract Image getCoverImage(); @@ -116,10 +131,12 @@ public abstract class PreviewWidgetBlock extends JPanel implements MouseListe public void mouseMoved(MouseEvent e) { Dimension dimension = getCoverDimension(); Rectangle containerRec = new Rectangle(0, 0, dimension.width, dimension.height); - if (containerRec.contains(e.getX(), e.getY())) { - this.showPreviewPane(); - } else { - this.hidePreviewPane(); + if (!isRightClickPopupMenuVisible()) { + if (containerRec.contains(e.getX(), e.getY())) { + this.showPreviewPane(); + } else { + this.hidePreviewPane(); + } } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java index 05507a786..1e9ca55a1 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java @@ -40,7 +40,7 @@ import java.util.List; * @Author: Yuan.Wang * @Date: 2020/11/5 */ -class GroupPane extends JPanel { +public class GroupPane extends JPanel { private static final Icon downIcon = IOUtils.readIcon("/com/fr/base/images/share/arrow_down.png"); private static final Icon rightIcon = IOUtils.readIcon("/com/fr/base/images/share/arrow_right.png"); private static final int DEFAULT_HEIGHT = 24; diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java index 44bdd0fa5..90f1f30c2 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java @@ -1,6 +1,8 @@ package com.fr.design.mainframe.share.ui.local; import com.fr.design.mainframe.share.AbstractWidgetSelectPane; +import com.fr.design.mainframe.share.ui.base.AbstractWidgetPopupPreviewPane; +import com.fr.design.mainframe.share.ui.base.LocalWidgetPopupPreviewPane; import com.fr.design.mainframe.share.ui.block.LocalWidgetBlock; import com.fr.form.share.DefaultSharableWidget; import com.fr.form.share.SharableWidgetProvider; @@ -22,7 +24,7 @@ import java.awt.event.MouseEvent; /** * created by Harrison on 2020/03/23 **/ -public class LocalWidgetSelectPane extends AbstractWidgetSelectPane { +public class LocalWidgetSelectPane extends AbstractWidgetSelectPane { private LocalWidgetBlock selectedBlock; private final Group group; @@ -105,6 +107,11 @@ public class LocalWidgetSelectPane extends AbstractWidgetSelectPane { return selectedBlock; } + @Override + protected AbstractWidgetPopupPreviewPane createPopupPreviewPane() { + return new LocalWidgetPopupPreviewPane(); + } + @Override protected Container getParentContainer() { return this.getParent().getParent(); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetPopupPreviewPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetPopupPreviewPane.java new file mode 100644 index 000000000..736377f06 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetPopupPreviewPane.java @@ -0,0 +1,212 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.design.designer.IntervalConstants; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.AbstractWidgetPopupPreviewPane; +import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.general.FRFont; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Image; +import java.awt.Toolkit; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/14 + */ +public class OnlineWidgetPopupPreviewPane extends AbstractWidgetPopupPreviewPane { + private static final int POPUP_WIDTH = 412; + private static final int POPUP_TOP_HEIGHT = 28; + private static final int POPUP_BOTTOM_HEIGHT = 54; + + private PreviewImagePane previewImagePane; + private UILabel versionLabel; + private UILabel downloadsLabel; + private UILabel priceLabel; + + private final JPanel suitableThemeNamePane; + private UILabel suitableThemeNameLabel; + + public OnlineWidgetPopupPreviewPane() { + setPreferredSize(new Dimension(POPUP_WIDTH, getPreferredSize().height)); + setLayout(new BorderLayout(0, 0)); + setOpaque(true); + setBackground(new Color(0xF0F0F1)); + + suitableThemeNamePane = createSuitableThemeNamePane(); + JPanel previewImagePane = createPreviewImagePane(); + JPanel widgetInfoPane = createWidgetInfoPane(); + + addComponents(suitableThemeNamePane, previewImagePane, widgetInfoPane); + } + + private JPanel createSuitableThemeNamePane() { + suitableThemeNameLabel = new UILabel(); + suitableThemeNameLabel.setOpaque(false); + suitableThemeNameLabel.setBackground(new Color(0xF5F5F7)); + suitableThemeNameLabel.setIcon(IOUtils.readIcon("/com/fr/design/icon/icon_predefined_style.png")); + suitableThemeNameLabel.setIconTextGap(IntervalConstants.INTERVAL_L6); + + JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane(); + content.setPreferredSize(new Dimension(POPUP_WIDTH, POPUP_TOP_HEIGHT)); + content.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + content.setOpaque(true); + content.setBackground(new Color(0xF5F5F7)); + content.add(suitableThemeNameLabel, BorderLayout.CENTER); + + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.add(content, BorderLayout.CENTER); + + JSeparator separator = new JSeparator(); + separator.setPreferredSize(new Dimension(POPUP_WIDTH, 1)); + separator.setBackground(new Color(0xE8E8E9)); + container.add(separator, BorderLayout.SOUTH); + + return container; + } + + private JPanel createPreviewImagePane() { + previewImagePane = new PreviewImagePane(); + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); + container.add(previewImagePane, BorderLayout.CENTER); + return container; + } + + private JPanel createWidgetInfoPane() { + versionLabel = new UILabel(); + versionLabel.setVerticalAlignment(SwingConstants.CENTER); + versionLabel.setFont(FRFont.getInstance(versionLabel.getFont()).deriveFont(12.0F)); + + downloadsLabel = new UILabel(); + downloadsLabel.setVerticalAlignment(SwingConstants.TOP); + downloadsLabel.setFont(FRFont.getInstance(downloadsLabel.getFont()).deriveFont(12.0F)); + + priceLabel = new UILabel(); + priceLabel.setVerticalAlignment(SwingConstants.CENTER); + priceLabel.setHorizontalAlignment(SwingConstants.RIGHT); + priceLabel.setFont(FRFont.getInstance(priceLabel.getFont()).deriveFont(14.0F)); + priceLabel.setForeground(new Color(0xE65251)); + + JPanel container = new JPanel(); + container.setPreferredSize(new Dimension(POPUP_WIDTH - 20, POPUP_BOTTOM_HEIGHT)); + container.setLayout(new GridBagLayout()); + container.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + + GridBagConstraints constraints = new GridBagConstraints(); + constraints.fill = GridBagConstraints.BOTH; + + constraints.gridx = 0; + constraints.gridy = 0; + constraints.gridwidth = 1; + constraints.gridheight = 1; + constraints.weightx = 1; + constraints.weighty = 1; + container.add(versionLabel, constraints); + + constraints.gridx = 0; + constraints.gridy = 1; + constraints.gridwidth = 1; + constraints.gridheight = 1; + constraints.weightx = 1; + constraints.weighty = 1; + container.add(downloadsLabel, constraints); + + constraints.gridx = 1; + constraints.gridy = 0; + constraints.gridwidth = 1; + constraints.gridheight = 2; + constraints.weightx = 1; + constraints.weighty = 2; + container.add(priceLabel, constraints); + + return container; + } + + private void addComponents(JComponent... components) { + if (components == null) { + return; + } + JComponent container = this; + for (int i = 0; i < components.length; i++) { + JComponent component = components[i]; + if (component != null) { + container.add(component, BorderLayout.NORTH); + if (i < components.length - 1) { + JPanel nextContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.add(nextContainer, BorderLayout.CENTER); + container = nextContainer; + } + } + } + } + + @Override + public void populateBean(PreviewWidgetBlock block) { + OnlineShareWidget widget = block.getWidget(); + String themeName = widget.getThemeName(); + if (StringUtils.isNotEmpty(themeName)) { + suitableThemeNamePane.setVisible(true); + suitableThemeNameLabel.setText(themeName); + } else { + suitableThemeNamePane.setVisible(false); + } + + String priceText = "¥" + widget.getPrice(); + if (widget.getPrice() <= 0) { + priceText = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Price_Free"); + } + priceLabel.setText(priceText); + + versionLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Version") + ": " + widget.getDesignerVersion()); + downloadsLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Download_Times") + ": " + widget.getDownloadTimes()); + previewImagePane.setPreviewImage(block.getPreviewImage()); + + int height = (suitableThemeNamePane.isVisible() ? POPUP_TOP_HEIGHT : 0) + 10 + previewImagePane.getPreferredSize().height + POPUP_BOTTOM_HEIGHT; + setPreferredSize(new Dimension(POPUP_WIDTH, height)); + } + + private static class PreviewImagePane extends JPanel { + private static final Image DEFAULT_IMAGE = IOUtils.readImage("com/fr/base/images/share/component_error.png"); + private static final int PREVIEW_IMAGE_WIDTH = POPUP_WIDTH - 20; + private static final int STANDARD_DPI = 128; + + private Image previewImage; + + public void setPreviewImage(Image previewImage) { + this.previewImage = previewImage; + if (this.previewImage == null) { + this.previewImage = DEFAULT_IMAGE; + } + + int dpi = Toolkit.getDefaultToolkit().getScreenResolution(); + int imageWidth = this.previewImage.getWidth(null); + int imageHeight = this.previewImage.getHeight(null); + + double imageAspectRatio = (double) imageWidth / imageHeight; + int width = (PREVIEW_IMAGE_WIDTH * dpi) / STANDARD_DPI; + int height = (int) (width / imageAspectRatio); + setPreferredSize(new Dimension(width, height)); + } + + @Override + public void paint(Graphics g) { + g.drawImage(this.previewImage, 0, 0, getWidth(), getHeight(), null); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java index c07485745..2d8bcfdbe 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java @@ -24,7 +24,6 @@ import java.awt.Cursor; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.MouseEvent; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; @@ -34,13 +33,29 @@ import java.util.concurrent.ExecutionException; */ public class OnlineWidgetRepoPane extends BasicPane { private static final String MARKET_URL = "https://market.fanruan.com/reuse"; + private static List[] sharableWidgets; private OnlineWidgetTabPane componentTabPane; private JPanel centerPane; private boolean isShowPackagePanel = false; private CardLayout cardLayout; + private Status currentStatus; + enum Status {LOADING, DISCONNECTED, NORMAL} + public static boolean loadWidgets() { + if (sharableWidgets != null){ + return true; + } + try{ + sharableWidgets = ShareUtils.getAllSharableWidgetsFromShop(); + return true; + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return false; + } + } + public static OnlineWidgetRepoPane getInstance() { return OnlineWidgetRepoPane.HOLDER.singleton; } @@ -77,7 +92,16 @@ public class OnlineWidgetRepoPane extends BasicPane { this.add(createInternetErrorPane(), Status.DISCONNECTED.name()); switchPane(Status.LOADING); - synchronizedLoadingContent(); + setContent(); + } + + private void setContent() { + if (sharableWidgets != null) { + initContentPane(); + addCenterPane(); + } else { + synchronizedLoadingContent(); + } } private void addCenterPane() { @@ -91,6 +115,7 @@ public class OnlineWidgetRepoPane extends BasicPane { } private void switchPane(Status status) { + this.currentStatus = status; cardLayout.show(this, status.name()); } @@ -100,7 +125,6 @@ public class OnlineWidgetRepoPane extends BasicPane { protected Boolean doInBackground() throws Exception { return initContentPane(); } - @Override protected void done() { try { @@ -118,24 +142,19 @@ public class OnlineWidgetRepoPane extends BasicPane { } private boolean initContentPane() { - List sharableWidgets = new ArrayList<>(); - List sharableWidgetPackage = new ArrayList<>(); - - try { - ShareUtils.getAllSharableWidgetsFromShop(sharableWidgets, sharableWidgetPackage); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + boolean loadWidgetsSuccess = loadWidgets(); + if (loadWidgetsSuccess) { + this.componentTabPane = new OnlineWidgetTabPane(sharableWidgets[0].toArray(new OnlineShareWidget[sharableWidgets[0].size()]), + sharableWidgets[1].toArray(new OnlineShareWidget[sharableWidgets[1].size()])); + } else { switchPane(Status.DISCONNECTED); - return false; } - this.componentTabPane = new OnlineWidgetTabPane(sharableWidgets.toArray(new OnlineShareWidget[sharableWidgets.size()]), - sharableWidgetPackage.toArray(new OnlineShareWidget[sharableWidgetPackage.size()])); - - return true; + return loadWidgetsSuccess; } private void reload() { this.removeAll(); + sharableWidgets = null; initPane(); this.validate(); this.repaint(); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java index 61e3ced83..c1a556fc5 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java @@ -3,6 +3,7 @@ package com.fr.design.mainframe.share.ui.online; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.share.AbstractWidgetSelectPane; +import com.fr.design.mainframe.share.ui.base.AbstractWidgetPopupPreviewPane; import com.fr.design.mainframe.share.ui.base.LoadingPane; import com.fr.design.mainframe.share.ui.base.NoMatchPane; import com.fr.design.mainframe.share.ui.base.PagingFiledPane; @@ -30,7 +31,7 @@ import java.util.concurrent.ExecutionException; /** * Created by kerry on 2020-10-19 */ -public class OnlineWidgetSelectPane extends AbstractWidgetSelectPane { +public class OnlineWidgetSelectPane extends AbstractWidgetSelectPane { protected static final int H_GAP = 5; protected static final int V_GAP = 10; @@ -219,6 +220,11 @@ public class OnlineWidgetSelectPane extends AbstractWidgetSelectPane { } } + @Override + protected AbstractWidgetPopupPreviewPane createPopupPreviewPane() { + return new OnlineWidgetPopupPreviewPane(); + } + protected Container getParentContainer() { return this.getParent(); } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java index 2271f0c89..15b880483 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java @@ -25,8 +25,8 @@ public class OnlineWidgetPackageSelectPane extends OnlineWidgetSelectPane { } - public void showWidgetDetailPane(String id) { - this.parentPane.showWidgetDetailPane(id); + public void showWidgetDetailPane(OnlineShareWidget widgetPackage) { + this.parentPane.showWidgetDetailPane(widgetPackage); } protected PreviewWidgetBlock createWidgetBlock(OnlineShareWidget provider) { diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java index 887b7c34a..662df3d8d 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java @@ -150,10 +150,11 @@ public class OnlineWidgetPackagesShowPane extends AbstractOnlineWidgetShowPane { return onlineShareWidgets.toArray(new OnlineShareWidget[onlineShareWidgets.size()]); } - public void showWidgetDetailPane(final String id) { + public void showWidgetDetailPane(final OnlineShareWidget widgetPackage) { + String id = widgetPackage.getId(); currentPackageId = id; boolean containsCache = cachePanelMap.containsKey(id); - onlineWidgetSelectPane = containsCache ? cachePanelMap.get(id) : new OnlineWidgetSelectPane(() -> ShareUtils.getPackageWidgets(id), 50); + onlineWidgetSelectPane = containsCache ? cachePanelMap.get(id) : new OnlineWidgetSelectPane(() -> ShareUtils.getPackageWidgets(widgetPackage), 50); downloadLabel.setVisible(!containsCache); showWidgetDetailPane(onlineWidgetSelectPane); } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java index 96c2cc28c..c5b90c785 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java @@ -1,5 +1,6 @@ package com.fr.design.mainframe.share.util; +import com.fr.base.theme.FormTheme; import com.fr.design.DesignerEnvManager; import com.fr.design.extra.PluginConstants; import com.fr.form.share.base.CancelCheck; @@ -9,6 +10,10 @@ import com.fr.general.CloudCenter; import com.fr.log.FineLoggerFactory; import com.fr.stable.ProductConstants; import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLReaderHelper; +import com.fr.stable.xml.XMLableReader; import com.fr.third.org.apache.http.HttpEntity; import com.fr.third.org.apache.http.HttpException; import com.fr.third.org.apache.http.HttpStatus; @@ -23,9 +28,12 @@ import com.fr.third.org.apache.http.impl.client.HttpClients; import org.jetbrains.annotations.NotNull; import javax.crypto.Cipher; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; +import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.interfaces.RSAPublicKey; @@ -130,6 +138,40 @@ public class DownloadUtils { } } + public static FormTheme downloadThemeFile(String themePath) { + try { + CloseableHttpResponse fileRes = getHttpResponse(themePath); + if (fileRes.getStatusLine().getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY) { + fileRes = getHttpResponse(fileRes.getHeaders("Location")[0].getValue()); + } + if (fileRes.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + HttpEntity entity = fileRes.getEntity(); + + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(), StandardCharsets.UTF_8)); + StringBuilder stringBuilder = new StringBuilder(); + String line; + while ((line = bufferedReader.readLine()) != null) { + stringBuilder.append(line); + } + + String content = stringBuilder.toString(); + XMLableReader reader = XMLReaderHelper.createXMLableReader(new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), XMLPrintWriter.XML_ENCODER); + + FormTheme theme = new FormTheme(); + reader.readXMLObject(theme); + if (StringUtils.isNotEmpty(theme.getName())) { + return theme; + } + } else { + FineLoggerFactory.getLogger().info("download theme {} failed", themePath); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + + return null; + } + private static CloseableHttpResponse getHttpResponse(String url, String id) throws Exception { //先登录一下。不然可能失败 CloseableHttpClient client = createClient(); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java index 8c88de20b..b66c2458c 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java @@ -32,19 +32,23 @@ public class InstallComponentHelper { public static void installPreComponent() { if (needPreInstallComponent()) { - for (String componentPath : PRE_INSTALL_COMPONENTS) { - try { - InputStream inputStream = InstallComponentHelper.class.getResourceAsStream(StableUtils.pathJoin(PRE_INSTALL_PATH, componentPath)); - byte[] data = ResourceIOUtils.inputStream2Bytes(inputStream); - WorkContext.getWorkResource().write(StableUtils.pathJoin(ComponentPath.SHARE_PATH.path(), componentPath), data); - } catch (Exception e) { - FineLoggerFactory.getLogger().error("install Component filed" + e.getMessage(), e); - } - } + installShareComponents(PRE_INSTALL_PATH, PRE_INSTALL_COMPONENTS); } } + public static void installShareComponents(String resourcePath, String[] components) { + for (String componentPath : components) { + try { + InputStream inputStream = InstallComponentHelper.class.getResourceAsStream(StableUtils.pathJoin(resourcePath, componentPath)); + byte[] data = ResourceIOUtils.inputStream2Bytes(inputStream); + WorkContext.getWorkResource().write(StableUtils.pathJoin(ComponentPath.SHARE_PATH.path(), componentPath), data); + } catch (Exception e) { + FineLoggerFactory.getLogger().error("install Component filed" + e.getMessage(), e); + } + } + } + private static boolean needPreInstallComponent() { try { //老用户或者组件库里已有组件,不预装组件 diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java index 0dd613975..c9da57391 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java @@ -3,6 +3,7 @@ package com.fr.design.mainframe.share.util; import com.fr.base.io.IOFile; import com.fr.base.iofile.attr.ExtendSharableAttrMark; import com.fr.base.theme.FormTheme; +import com.fr.base.theme.FormThemeConfig; import com.fr.base.theme.TemplateTheme; import com.fr.base.theme.TemplateThemeCompatible; import com.fr.design.designer.creator.XCreator; @@ -58,9 +59,11 @@ public class ShareComponentUtils { JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); TemplateTheme theme = template.getTemplateTheme(); if (theme instanceof FormTheme) { + String themeName4LegacyTemplate = FormThemeConfig.getInstance().getThemeName4LegacyTemplate(); boolean isCurrentUsingThemeSuitSharedComponent = StringUtils.isNotEmpty(theme.getName()) && StringUtils.isNotEmpty(suitableTemplateThemeName) && - StringUtils.equals(theme.getName(), suitableTemplateThemeName); + StringUtils.equals(theme.getName(), suitableTemplateThemeName) && + !StringUtils.equals(theme.getName(), themeName4LegacyTemplate); XCreatorUtils.setupTemplateTheme(creator, false, (FormTheme) theme, isCurrentUsingThemeSuitSharedComponent ? TemplateThemeCompatible.NONE : TemplateThemeCompatible.ABSENT); } return creator; diff --git a/designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java b/designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java index 5f45b57b0..62eebdf21 100644 --- a/designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java @@ -10,6 +10,8 @@ import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XWParameterLayout; import com.fr.design.designer.properties.PropertyTab; import com.fr.design.file.HistoryTemplateListPane; +import com.fr.design.fit.DesignerUIModeConfig; +import com.fr.design.fit.common.TemplateTool; import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.fun.ParameterExpandablePaneUIProvider; import com.fr.design.gui.ibutton.UIButtonGroup; @@ -20,8 +22,11 @@ import com.fr.design.gui.itextfield.UITextField; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.FormDesigner; +import com.fr.design.mainframe.FormSelection; import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.widget.accessibles.AccessibleBackgroundEditor; +import com.fr.design.utils.gui.LayoutUtils; import com.fr.design.utils.gui.UIComponentUtils; import com.fr.design.widget.ui.designer.AbstractDataModify; import com.fr.design.widget.ui.designer.component.UIBoundSpinner; @@ -35,6 +40,7 @@ import javax.swing.Icon; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Component; +import java.awt.Rectangle; import java.util.Set; /** @@ -43,18 +49,19 @@ import java.util.Set; public class RootDesignDefinePane extends AbstractDataModify { private XWParameterLayout root; private UISpinner designerWidth; + private UISpinner paraHeight; private UICheckBox displayReport; private UICheckBox useParamsTemplate; private AccessibleBackgroundEditor background; private UIButtonGroup hAlignmentPane; private UITextField labelNameTextField; - /** - * 插件带来的额外属性 - */ + //是否是新设计模式下决策报表 + private boolean newForm; private PropertyGroupPane extraPropertyGroupPane; public RootDesignDefinePane(XCreator xCreator) { super(xCreator); + newForm = TemplateTool.getCurrentEditingNewJForm() != null && DesignerUIModeConfig.getInstance().newUIMode(); this.root = (XWParameterLayout) xCreator; initComponent(); } @@ -62,7 +69,11 @@ public class RootDesignDefinePane extends AbstractDataModify { public void initComponent() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); - designerWidth = new UIBoundSpinner(1, Integer.MAX_VALUE, 1); + if (newForm) { + paraHeight = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0); + } else { + designerWidth = new UIBoundSpinner(1, Integer.MAX_VALUE, 1); + } JPanel advancePane = createAdvancePane(); UIExpandablePane advanceExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), 280, 20, advancePane); this.add(advanceExpandablePane, BorderLayout.NORTH); @@ -70,7 +81,6 @@ public class RootDesignDefinePane extends AbstractDataModify { UIExpandablePane layoutExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Size"), 280, 20, layoutPane); this.add(layoutExpandablePane, BorderLayout.CENTER); this.addExtraUIExpandablePaneFromPlugin(); - } private void addExtraUIExpandablePaneFromPlugin() { @@ -92,9 +102,9 @@ public class RootDesignDefinePane extends AbstractDataModify { double[] rowSize = {p}; double[] columnSize = {p, f}; int[][] rowCount = {{1, 1}}; - Component[][] components = new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Desin_Width")), designerWidth}, - }; + Component[] component = newForm ? new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Design_Height")), paraHeight} : + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Desin_Width")), designerWidth}; + Component[][] components = new Component[][]{component}; JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); @@ -103,6 +113,21 @@ public class RootDesignDefinePane extends AbstractDataModify { } public JPanel createAdvancePane() { + if (newForm) { + return getNewFormAdvancePane(); + } else { + return getTemplateAdvancePane(); + } + } + + /** + * @Description: 获取的非新决策报表AdvancePane + * @param + * @return: + * @Author: Henry.Wang + * @date: 2020/11/05 15:36 + */ + private JPanel getTemplateAdvancePane() { JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); labelNameTextField = new UITextField(); displayReport = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Display_Nothing_Before_Query")); @@ -139,6 +164,40 @@ public class RootDesignDefinePane extends AbstractDataModify { return jPanel; } + /** + * @Description: 获取新决策报表的AdvancePane + * @param + * @return: + * @Author: Henry.Wang + * @date: 2020/11/05 15:36 + */ + private JPanel getNewFormAdvancePane() { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + labelNameTextField = new UITextField(); + displayReport = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Display_Nothing_Before_Query")); + UIComponentUtils.setLineWrap(displayReport); + useParamsTemplate = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Use_Params_Template")); + background = new AccessibleBackgroundEditor(); + + double f = TableLayout.FILL; + double p = TableLayout.PREFERRED; + double[] rowSize = {p, p, p, p}; + double[] columnSize = {p, f}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}}; + Component[][] components = new Component[][]{ + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Label_Name")), labelNameTextField}, + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Base_Background")), background}, + new Component[]{displayReport, null}, + new Component[]{useParamsTemplate, null} + }; + JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_L1); + panel.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); + + jPanel.add(panel, BorderLayout.NORTH); + + return jPanel; + } + @Override public String title4PopupWindow() { return "parameter"; @@ -150,17 +209,37 @@ public class RootDesignDefinePane extends AbstractDataModify { background.setValue(ob.getBackground()); displayReport.setSelected(ob.isDelayDisplayContent()); useParamsTemplate.setSelected(ob.isUseParamsTemplate()); - designerWidth.setValue(ob.getDesignWidth()); - hAlignmentPane.setSelectedItem(ob.getPosition()); + if (newForm) { + FormDesigner designer = TemplateTool.getCurrentEditingNewJForm().getFormDesign(); + paraHeight.setValue(designer.getParaHeight()); + } else { + designerWidth.setValue(ob.getDesignWidth()); + hAlignmentPane.setSelectedItem(ob.getPosition()); - if (extraPropertyGroupPane != null) { - extraPropertyGroupPane.populate(ob); + if (extraPropertyGroupPane != null) { + extraPropertyGroupPane.populate(ob); + } } } @Override public WParameterLayout updateBean() { + if (newForm) { + return updateNewFormBean(); + } else { + return updateTemplateBean(); + } + } + + /** + * @Description: 更新非新决策报表的bean + * @param + * @return: + * @Author: Henry.Wang + * @date: 2020/11/05 15:36 + */ + private WParameterLayout updateTemplateBean() { WParameterLayout wParameterLayout = (WParameterLayout) creator.toData(); wParameterLayout.setLabelName(labelNameTextField.getText()); if (isCompsOutOfDesignerWidth((int) designerWidth.getValue())) { @@ -173,22 +252,56 @@ public class RootDesignDefinePane extends AbstractDataModify { JTemplate jTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); jTemplate.needAddTemplateIdAttr(useParamsTemplate.isSelected()); wParameterLayout.setBackground((Background) background.getValue()); - wParameterLayout.setPosition((int) hAlignmentPane.getSelectedItem()); + wParameterLayout.setPosition((Integer) hAlignmentPane.getSelectedItem()); return wParameterLayout; } - private boolean isCompsOutOfDesignerWidth(int designerWidth){ - for(int i=0; i designerWidth){ + if (comp.getX() + comp.getWidth() > designerWidth) { return true; } } return false; } + @Override public DataCreatorUI dataUI() { return null; } - } diff --git a/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java b/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java index 908defcbb..cb04f9345 100644 --- a/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java +++ b/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java @@ -43,8 +43,8 @@ public class DeveloperPreview extends AbstractPreviewProvider { @Override public void onClick(JTemplate jt) { - MutilTempalteTabPane.getInstance().closeCurrentTpl(); super.onClick(jt); + MutilTempalteTabPane.getInstance().closeCurrentTpl(); } diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/EmptyLayoutPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/EmptyLayoutPane.java new file mode 100644 index 000000000..f17b258f9 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/EmptyLayoutPane.java @@ -0,0 +1,36 @@ +package com.fr.design.widget.ui.designer; + +import com.fr.base.svg.IconUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; + +public class EmptyLayoutPane extends PredefinedLayoutPane { + public EmptyLayoutPane() { + this.setLayout(new BorderLayout()); + this.setPreferredSize(new Dimension(234, 1)); + this.setBackground(Color.WHITE); + UILabel newFormIcon = new UILabel(IconUtils.readIcon("/com/fr/design/form/images/new_form.png")); + newFormIcon.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEmptyBorder(39, 105, 0, 105), + BorderFactory.createDashedBorder(Color.BLACK, 1.0f, 2.0f, 2.0f, true) + )); + UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_New_Empty_Template")); + label.setBorder(BorderFactory.createEmptyBorder(0, 78, 30, 0)); + + this.add(newFormIcon, BorderLayout.NORTH); + this.add(label, BorderLayout.CENTER); + + this.initListener(); + } + + @Override + public String getTemplatePath() { + return StringUtils.EMPTY; + } +} diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/FieldEditorDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/FieldEditorDefinePane.java index 45c2cd968..4ee699e0f 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/FieldEditorDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/FieldEditorDefinePane.java @@ -1,9 +1,17 @@ package com.fr.design.widget.ui.designer; +import com.fr.design.ExtraDesignClassManager; +import com.fr.design.beans.ErrorMsgTextFieldAdapter; +import com.fr.design.beans.UITextFieldAdapter; import com.fr.design.constants.LayoutConstants; import com.fr.design.designer.IntervalConstants; -import com.fr.design.designer.creator.*; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XCreatorUtils; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XWFitLayout; +import com.fr.design.designer.creator.XWParameterLayout; import com.fr.design.foldablepane.UIExpandablePane; +import com.fr.design.fun.TextFieldAdapterProvider; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itextfield.UITextField; @@ -11,19 +19,19 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.widget.ui.designer.component.FontSizeComboPane; import com.fr.form.ui.FieldEditor; +import com.fr.log.FineLoggerFactory; - -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import java.awt.*; +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Component; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; public abstract class FieldEditorDefinePane extends AbstractDataModify { protected UICheckBox allowBlankCheckBox; // richer:错误信息,是所有控件共有的属性,所以放到这里来 - protected UITextField errorMsgTextField; + protected ErrorMsgTextFieldAdapter errorMsgTextField; protected JPanel validatePane; protected FontSizeComboPane fontSizePane; protected UITextField labelNameTextField; @@ -40,7 +48,6 @@ public abstract class FieldEditorDefinePane extends Abstr allowBlankCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Allow_Null")); allowBlankCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); fontSizePane = new FontSizeComboPane(); - errorMsgTextField = new UITextField(); JPanel contentPane = this.setFirstContentPane(); JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); jPanel.add(contentPane, BorderLayout.CENTER); @@ -76,23 +83,17 @@ public abstract class FieldEditorDefinePane extends Abstr protected void initErrorMsgPane() { // 错误信息 - errorMsgTextField = new UITextField(); -// // richer:主要为了方便查看比较长的错误信息 - errorMsgTextField.getDocument().addDocumentListener(new DocumentListener() { - - public void changedUpdate(DocumentEvent e) { - errorMsgTextField.setToolTipText(errorMsgTextField.getText()); - } - - public void insertUpdate(DocumentEvent e) { - errorMsgTextField.setToolTipText(errorMsgTextField.getText()); - } - - public void removeUpdate(DocumentEvent e) { - errorMsgTextField.setToolTipText(errorMsgTextField.getText()); - } - }); - + TextFieldAdapterProvider provider = ExtraDesignClassManager.getInstance().getSingle(TextFieldAdapterProvider.XML_TAG); + if (provider == null) { + errorMsgTextField = new UITextFieldAdapter(); + return; + } + try { + errorMsgTextField = provider.createTextFieldAdapter(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + errorMsgTextField = new UITextFieldAdapter(); + } } @@ -111,7 +112,7 @@ public abstract class FieldEditorDefinePane extends Abstr validatePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); final UILabel uiLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Error_Tip")); JPanel borderPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - final JPanel errorTipPane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{uiLabel, errorMsgTextField}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_MEDIUM); + final JPanel errorTipPane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{uiLabel, errorMsgTextField.getErrorMsgTextField()}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_MEDIUM); errorTipPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L6, IntervalConstants.INTERVAL_L5, 0, 0)); borderPane.add(errorTipPane, BorderLayout.CENTER); allowBlankCheckBox.addItemListener(new ItemListener() { diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/NewFormPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/NewFormPane.java new file mode 100644 index 000000000..dfa156d5e --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/NewFormPane.java @@ -0,0 +1,360 @@ +package com.fr.design.widget.ui.designer; + +import com.fr.base.iofile.attr.TemplateLayoutIdAttrMark; +import com.fr.design.border.UITitledMatteBorder; +import com.fr.design.designer.beans.PredefinedLayout; +import com.fr.design.designer.beans.models.NewFormModel; +import com.fr.design.dialog.BasicPane; +import com.fr.design.dialog.DialogActionListener; +import com.fr.design.dialog.UIDialog; +import com.fr.design.gui.ibutton.UIButtonGroup; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.BaseJForm; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.form.main.Form; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.OccupiedLayout; +import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; +import com.fr.form.ui.container.WBorderLayout; +import com.fr.form.ui.container.WFitLayout; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; +import com.fr.stable.bridge.StableFactory; + +import javax.swing.BorderFactory; +import javax.swing.DefaultListCellRenderer; +import javax.swing.DefaultListModel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListSelectionModel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class NewFormPane extends BasicPane { + private static final String EMPTY_FORM_LAYOUTID = "9ebf6aff-ad53-45a9-a175-9633f4162a3a"; + + private NewFormModel newFormModel; + private UIDialog dialog; + private PredefinedLayoutPane selectedLayoutPane = null; + private Map layoutPaneMap = new HashMap<>(); + private List layoutCards = new ArrayList<>(); + + public NewFormPane() { + newFormModel = NewFormModel.getInstance(); + this.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0)); + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.add(createModuleListPane(), BorderLayout.WEST); + this.add(createTemplateManagePane(), BorderLayout.CENTER); + initWindow(); + } + + private void initWindow() { + dialog = new UIDialog(DesignerContext.getDesignerFrame(), this) { + @Override + public void checkValid() throws Exception { + + } + }; + dialog.setButtonEnabled(false); + dialog.addDialogActionListener(new DialogActionListener() { + @Override + public void doOk() { + createLayoutForm(); + } + + @Override + public void doCancel() { + + } + }); + dialog.setSize(new Dimension(900, 600)); + GUICoreUtils.centerWindow(dialog); + dialog.setTitle(this.title4PopupWindow()); + dialog.setResizable(false); + } + + public void createLayoutForm() { + if (selectedLayoutPane != null) { + NewFormPane.this.newForm(selectedLayoutPane.getTemplatePath()); + } + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_New_Template"); + } + + public UIDialog getWindow() { + return dialog; + } + + public void showWindow() { + dialog.setVisible(true); + } + + private JPanel createModuleListPane() { + JList list = new JList(); + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + list.setModel(initListModel()); + list.setSelectedIndex(0); + list.setCellRenderer(new DefaultListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + this.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); + return this; + } + }); + list.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + String value = list.getSelectedValue(); + int selectedIndex = list.getSelectedIndex(); + for (Map.Entry entry : layoutPaneMap.entrySet()) { + String moduleName = entry.getKey(); + JPanel module = entry.getValue(); + module.setVisible(selectedIndex == 0 || ComparatorUtils.equals(moduleName, value)); + } + } + }); + + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBackground(new Color(255, 255, 255)); + jPanel.setPreferredSize(new Dimension(138, 1)); + jPanel.add(new UIScrollPane(list), BorderLayout.CENTER); + return jPanel; + } + + private DefaultListModel initListModel() { + DefaultListModel model = new DefaultListModel<>(); + model.addElement(Toolkit.i18nText("Fine-Design_All_Template_Layout")); + Map> map = newFormModel.getConfig(); + for (String key : map.keySet()) { + model.addElement(key); + } + return model; + } + + private JPanel createTemplateManagePane() { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.add(createTemplateManageNorthPane(), BorderLayout.NORTH); + jPanel.add(createTemplateManageSouthPane(), BorderLayout.CENTER); + return jPanel; + } + + private JPanel createTemplateManageNorthPane() { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); + jPanel.setPreferredSize(new Dimension(1, 129)); + jPanel.add(createNewTemplatePane(), BorderLayout.WEST); + jPanel.add(createSwitchButtonPane(), BorderLayout.EAST); + return jPanel; + } + + private JPanel createNewTemplatePane() { + EmptyLayoutPane jPanel = new EmptyLayoutPane(); + jPanel.addClickListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + setSelectedLayoutPane(jPanel); + dialog.setButtonEnabled(true); + } + }); + return jPanel; + } + + private JPanel createSwitchButtonPane() { + UIButtonGroup buttonGroup = new UIButtonGroup(new String[] { + Toolkit.i18nText("Fine-Design_Simple_Style_Template"), + Toolkit.i18nText("Fine-Design_Real_Style_Template") + }); + buttonGroup.setPreferredSize(new Dimension(140, 20)); + buttonGroup.setSelectedIndex(1); + buttonGroup.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + int selectedIndex = buttonGroup.getSelectedIndex(); + for (PredefinedLayoutPane layoutCard : layoutCards) { + if (selectedIndex == 1) { + layoutCard.showRealStyle(); + } else { + layoutCard.showSimpleStyle(); + } + } + } + }); + + JPanel switchButtonPane = new JPanel(new BorderLayout()); + switchButtonPane.add(buttonGroup, BorderLayout.CENTER); + + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); + jPanel.add(switchButtonPane, BorderLayout.NORTH); + return jPanel; + } + + private JPanel createTemplateManageSouthPane() { + List predefinedLayoutPanes = createPredefinedLayoutPanes(); + JPanel selectionsPane = createSelectionsPane(predefinedLayoutPanes); + + UIScrollPane selectionsScrollPane = new UIScrollPane(selectionsPane); + selectionsScrollPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + + JPanel titlePane = new JPanel(new BorderLayout()); + titlePane.setBorder(UITitledMatteBorder.createTitledBorder(Toolkit.i18nText("Fine-Design_Select_Template"), new Color(1, 159, 222))); + titlePane.add(selectionsScrollPane, BorderLayout.CENTER); + + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0)); + jPanel.add(titlePane, BorderLayout.CENTER); + + return jPanel; + } + + private JPanel createSelectionsPane(List components) { + JPanel selectionsPane = new JPanel(); + JPanel container = new JPanel(new BorderLayout()); + for (int i = 0; i < components.size(); i++) { + JPanel component = components.get(i); + if (component != null) { + container.add(component, BorderLayout.NORTH); + JPanel nextContainer = new JPanel(new BorderLayout()); + container.add(nextContainer, BorderLayout.CENTER); + if (i == 0) { + selectionsPane = container; + } + container = nextContainer; + } + } + return selectionsPane; + } + + private List createPredefinedLayoutPanes() { + List jPanels = new ArrayList<>(); + Map> map = newFormModel.getConfig(); + for (Map.Entry> entry : map.entrySet()) { + String moduleName = entry.getKey(); + List layouts = entry.getValue(); + + JPanel module = createPredefinedLayoutPane(moduleName); + layoutPaneMap.put(moduleName, module); + for (PredefinedLayout layout : layouts) { + PredefinedLayoutPane predefinedLayoutPane = new PredefinedLayoutPane(layout); + predefinedLayoutPane.addClickListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + setSelectedLayoutPane(predefinedLayoutPane); + dialog.setButtonEnabled(true); + } + }); + module.add(predefinedLayoutPane); + layoutCards.add(predefinedLayoutPane); + } + jPanels.add(module); + } + return jPanels; + } + + private JPanel createPredefinedLayoutPane(String title) { + JPanel jp = new JPanel(); + UITitledMatteBorder explainBorder = UITitledMatteBorder.createTitledTopBorder(title, Color.BLACK); + jp.setBorder(explainBorder); + jp.setLayout(new GridLayout(0, 3, 5, 5)); + return jp; + } + + private void newForm(String path) { + BaseJForm jForm; + try { + Form form = initEmptyBodyForm(); + initLayoutInfo(form, path); + jForm = StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, new Object[]{form}, BaseJForm.class); + DesignerContext.getDesignerFrame().addAndActivateJTemplate((JTemplate) jForm); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + private Form initEmptyBodyForm() { + WFitLayout body = new WFitLayout("body"); + body.setContainerWidth(WBorderLayout.DEFAULT_WIDTH); + body.setContainerHeight(WBorderLayout.DEFAULT_HEIGHT); + WBorderLayout borderLayout = new WBorderLayout("form"); + borderLayout.addCenter(body); + return new Form(borderLayout); + } + + /** + * 通过布局文件的位置初始化Form对象的布局信息 + * + * @param form 新建的form对象 + * @param path 布局文件位置 + * @throws Exception + */ + private void initLayoutInfo(Form form, String path) throws Exception { + if (isNewEmptyForm(path)) { + initEmptyFormLayoutId(form); + } else { + Form layoutTemplate = new Form(); + layoutTemplate.readStream(NewFormPane.class.getResourceAsStream(path)); + + if (layoutTemplate.getBody() != null && layoutTemplate.getBody() instanceof WFitLayout) { + WFitLayout layoutTemplateBody = (WFitLayout) layoutTemplate.getBody(); + WFitLayout body = (WFitLayout) form.getBody(); + + body.setMargin(layoutTemplateBody.getMargin()); + body.setCompInterval(layoutTemplateBody.getCompInterval()); + for (int i = 0; i < layoutTemplateBody.getWidgetCount(); i++) { + Widget boundsWidget = layoutTemplateBody.getWidget(i); + if (boundsWidget != null && boundsWidget instanceof BoundsWidget) { + Widget widget = ((BoundsWidget) boundsWidget).getWidget(); + if (widget != null && widget instanceof OccupiedLayout) { + body.addWidget((Widget) boundsWidget.clone()); + } + } + } + + form.setLayoutId(layoutTemplate.getLayoutId()); + } + } + } + + private void initEmptyFormLayoutId(Form form) { + form.addAttrMark(new TemplateLayoutIdAttrMark(EMPTY_FORM_LAYOUTID)); + form.setLayoutId(EMPTY_FORM_LAYOUTID); + } + + private boolean isNewEmptyForm(String layoutTemplatePath) { + return StringUtils.isEmpty(layoutTemplatePath); + } + + private void setSelectedLayoutPane(PredefinedLayoutPane layoutPane) { + if (selectedLayoutPane != layoutPane) { + if (selectedLayoutPane != null) { + selectedLayoutPane.setSelected(false); + } + selectedLayoutPane = layoutPane; + if (selectedLayoutPane != null) { + selectedLayoutPane.setSelected(true); + } + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/PredefinedLayoutPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/PredefinedLayoutPane.java new file mode 100644 index 000000000..bde9b07ee --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/PredefinedLayoutPane.java @@ -0,0 +1,119 @@ +package com.fr.design.widget.ui.designer; + +import com.fr.base.GraphHelper; +import com.fr.base.svg.IconUtils; +import com.fr.design.designer.beans.PredefinedLayout; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.stable.Constants; +import com.fr.stable.StringUtils; + +import javax.swing.JPanel; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class PredefinedLayoutPane extends JPanel { + private static final Color HOVERING_BORDER_COLOR = new Color(65, 155, 249); + private static final Color HOVERING_SHADOW_COLOR = new Color(65, 155, 249, 51); + private CardLayout cardLayout = new CardLayout(); + protected boolean hovering = false; + protected boolean selected = false; + protected MouseAdapter clickListener; + protected String templatePath = StringUtils.EMPTY; + + public PredefinedLayoutPane() { + + } + + public PredefinedLayoutPane(PredefinedLayout predefinedLayout) { + this.templatePath = predefinedLayout.getTemplate(); + UILabel simpleStyle = new UILabel(IconUtils.readIcon(predefinedLayout.getSimpleStyle())); + UILabel realStyle = new UILabel(IconUtils.readIcon(predefinedLayout.getRealStyle())); + + this.setLayout(cardLayout); + this.add(realStyle, 0); + this.add(simpleStyle, 1); + this.setPreferredSize(new Dimension(235, 134)); + this.initListener(); + } + + protected void initListener() { + this.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + if (clickListener != null) { + clickListener.mouseClicked(e); + } + } + + @Override + public void mouseEntered(MouseEvent e) { + hovering = true; + repaint(); + } + + @Override + public void mouseExited(MouseEvent e) { + hovering = false; + repaint(); + } + }); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + if (hovering) { + g.setColor(HOVERING_SHADOW_COLOR); + GraphHelper.fillRect(g, 1, 1, this.getWidth() - 2, this.getHeight() - 2); + } + + if (selected || hovering) { + g.setColor(HOVERING_BORDER_COLOR); + Rectangle rectangle = new Rectangle(1, 1, this.getWidth() - 2, this.getHeight() - 2); + GraphHelper.draw(g, rectangle, Constants.LINE_MEDIUM); + } + } + + public void addClickListener(MouseAdapter clickListener) { + this.clickListener = clickListener; + } + + public void showSimpleStyle() { + cardLayout.last(this); + } + + public void showRealStyle() { + cardLayout.first(this); + } + + public boolean isHovering() { + return hovering; + } + + public void setHovering(boolean hovering) { + this.hovering = hovering; + } + + public boolean isSelected() { + return selected; + } + + public void setSelected(boolean selected) { + this.selected = selected; + repaint(); + } + + public String getTemplatePath() { + return templatePath; + } + + public void setTemplatePath(String templatePath) { + this.templatePath = templatePath; + } +} diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/TextFieldEditorDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/TextFieldEditorDefinePane.java index 2baea973c..6e6a2ff14 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/TextFieldEditorDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/TextFieldEditorDefinePane.java @@ -1,7 +1,9 @@ package com.fr.design.widget.ui.designer; +import com.fr.design.ExtraDesignClassManager; import com.fr.design.designer.IntervalConstants; import com.fr.design.designer.creator.XCreator; +import com.fr.design.fun.RegPaneProvider; import com.fr.design.gui.frpane.RegFieldPane; import com.fr.design.gui.frpane.RegPane; import com.fr.design.gui.ilable.UILabel; @@ -11,10 +13,12 @@ import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.widget.ui.designer.component.FormWidgetValuePane; import com.fr.form.ui.TextEditor; - +import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; -import javax.swing.*; -import java.awt.*; + +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.Component; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -65,27 +69,36 @@ public class TextFieldEditorDefinePane extends FieldEditorDefinePane widgetValueLabel.setVerticalAlignment(SwingConstants.TOP); Component[][] components = new Component[][]{ new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Label_Name")), labelNameTextField}, - new Component[]{widgetValueLabel, formWidgetValuePane}, + new Component[]{widgetValueLabel, formWidgetValuePane}, new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_WaterMark"), SwingConstants.LEFT), waterMarkDictPane}, new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Font_Size"), SwingConstants.LEFT), fontSizePane} }; double[] rowSize = {p, p, p, p, p, p}; - double[] columnSize = {p,f}; - int[][] rowCount = {{1, 1},{1, 3},{1, 1},{1, 1}}; - final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); + double[] columnSize = {p, f}; + int[][] rowCount = {{1, 1}, {1, 3}, {1, 1}, {1, 1}}; + final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); JPanel boundsPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); boundsPane.add(panel); return boundsPane; } - public JPanel setValidatePane(){ + public JPanel setValidatePane() { return regPane; } - protected RegFieldPane createRegPane() { - return new RegFieldPane(); + RegPaneProvider provider = ExtraDesignClassManager.getInstance().getSingle(RegPaneProvider.XML_TAG); + if (provider == null) { + return new RegFieldPane(); + } + + try { + return provider.createRegPane(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return new RegFieldPane(); + } } @Override @@ -102,7 +115,7 @@ public class TextFieldEditorDefinePane extends FieldEditorDefinePane @Override protected TextEditor updateSubFieldEditorBean() { - TextEditor ob = (TextEditor)creator.toData(); + TextEditor ob = (TextEditor) creator.toData(); this.regPane.update(ob); ob.setWaterMark(waterMarkDictPane.getText()); formWidgetValuePane.update(ob); diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/PaddingBoundPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/PaddingBoundPane.java index 856ff6a0c..a73104e28 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/PaddingBoundPane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/PaddingBoundPane.java @@ -14,6 +14,7 @@ import com.fr.form.ui.RichStyleWidgetProvider; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; import java.awt.BorderLayout; import java.awt.Component; @@ -37,10 +38,10 @@ public class PaddingBoundPane extends BasicPane { public void initBoundPane(int t, int b, int l, int r) { this.setLayout(FRGUIPaneFactory.createBorderLayout()); - top = new UISpinner(0, Integer.MAX_VALUE, 1, t); - bottom = new UISpinner(0, Integer.MAX_VALUE, 1, b); - left = new UISpinner(0, Integer.MAX_VALUE, 1, l); - right = new UISpinner(0, Integer.MAX_VALUE, 1, r); + top = new UISpinner(0, Integer.MAX_VALUE, 1, t, false); + bottom = new UISpinner(0, Integer.MAX_VALUE, 1, b, false); + left = new UISpinner(0, Integer.MAX_VALUE, 1, l, false); + right = new UISpinner(0, Integer.MAX_VALUE, 1, r, false); top.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate")); bottom.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate")); left.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate")); @@ -79,13 +80,32 @@ public class PaddingBoundPane extends BasicPane { } public void update(RichStyleWidgetProvider marginWidget) { - marginWidget.setMargin(updateBean()); + try { + marginWidget.setMargin(updateBean()); + } catch (UnsupportedOperationException e) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + populateBean(marginWidget.getMargin()); + } + }); + + } + } public PaddingMargin updateBean() { return new PaddingMargin((int) top.getValue(), (int) left.getValue(), (int) bottom.getValue(), (int) right.getValue()); } + @Override + public void setEnabled(boolean enabled) { + this.top.setEnabled(enabled); + this.left.setEnabled(enabled); + this.bottom.setEnabled(enabled); + this.right.setEnabled(enabled); + } + @Override protected String title4PopupWindow() { return "PaddingBoundPane"; diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ElementEditorDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ElementEditorDefinePane.java index 87c89f3cb..e32bc9b07 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ElementEditorDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ElementEditorDefinePane.java @@ -5,6 +5,8 @@ import com.fr.base.theme.TemplateTheme; import com.fr.base.theme.settings.ThemedComponentStyle; import com.fr.design.designer.IntervalConstants; import com.fr.design.designer.creator.*; +import com.fr.design.fit.DesignerUIModeConfig; +import com.fr.design.fit.attrpane.PcFitExpandablePane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.style.FollowingThemePane; import com.fr.design.layout.FRGUIPaneFactory; @@ -15,12 +17,15 @@ import com.fr.form.ui.ElementCaseEditor; import com.fr.form.ui.PaddingMargin; import com.fr.form.web.FormToolBarManager; import com.fr.general.ComparatorUtils; +import com.fr.report.fit.ReportFitAttr; import javax.swing.BorderFactory; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Component; +import java.util.ArrayList; +import java.util.List; /** * Created by ibm on 2017/8/7. @@ -29,6 +34,9 @@ public class ElementEditorDefinePane extends WTitleLayoutDefinePane 0) { + centerPane.add(extraPropertyGroupPane, BorderLayout.CENTER); + } + pcFitExpandablePane = new PcFitExpandablePane(this); + if (DesignerUIModeConfig.getInstance().newUIMode()) { + centerPane.add(pcFitExpandablePane, BorderLayout.SOUTH); + } + return centerPane; } + private CRPropertyDescriptor[] removeOldFitEditor(CRPropertyDescriptor[] extraTableEditor) { + if (!DesignerUIModeConfig.getInstance().newUIMode()) { + return extraTableEditor; + } + List list = new ArrayList(); + for (CRPropertyDescriptor crPropertyDescriptor : extraTableEditor) { + if (!ComparatorUtils.equals(FIT_STATE_PC, crPropertyDescriptor.getName())) { + list.add(crPropertyDescriptor); + } + } + return list.toArray(new CRPropertyDescriptor[list.size()]); + } + protected ElementCaseEditor updateSubBean() { ElementCaseEditor elementCaseEditor = (ElementCaseEditor) creator.toData(); if (themePane.isFollowingTheme() || ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate"))) { paddingBoundPane.update(elementCaseEditor); } elementCaseEditor.setToolBars((FormToolBarManager[]) elementCaseToolBarEditor.getValue()); - + ReportFitAttr fitAttr = pcFitExpandablePane.update(); + elementCaseEditor.setReportFitAttr(fitAttr); return elementCaseEditor; } + protected void populateSubBean(ElementCaseEditor ob) { paddingBoundPane.populate(ob); elementCaseToolBarEditor.setValue(ob.getToolBars()); extraPropertyGroupPane.populate(ob); + pcFitExpandablePane.populate(ob.getReportFitAttr()); } - } diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteBodyLayoutDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteBodyLayoutDefinePane.java index bc8dc9be0..6db75c171 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteBodyLayoutDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteBodyLayoutDefinePane.java @@ -4,13 +4,14 @@ import com.fr.base.io.IOFile; import com.fr.base.iofile.attr.WatermarkAttr; import com.fr.base.theme.FormTheme; import com.fr.base.theme.TemplateTheme; -import com.fr.base.theme.settings.ThemedComponentStyle; import com.fr.design.data.DataCreatorUI; import com.fr.design.designer.IntervalConstants; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XWFitLayout; import com.fr.design.designer.properties.items.FRLayoutTypeItems; import com.fr.design.designer.properties.items.Item; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.fit.DesignerUIModeConfig; import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.ilable.UILabel; @@ -19,6 +20,7 @@ import com.fr.design.gui.xpane.LayoutStylePane; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.WidgetPropertyPane; import com.fr.design.mainframe.widget.accessibles.AccessibleBodyWatermarkEditor; import com.fr.design.widget.FRWidgetFactory; @@ -36,6 +38,9 @@ import javax.swing.DefaultComboBoxModel; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Component; +import static javax.swing.JOptionPane.OK_CANCEL_OPTION; +import static javax.swing.JOptionPane.OK_OPTION; +import static javax.swing.JOptionPane.WARNING_MESSAGE; /** * Created by ibm on 2017/8/2. @@ -60,8 +65,9 @@ public class FRAbsoluteBodyLayoutDefinePane extends FRAbsoluteLayoutDefinePane { initUIComboBox(); this.setLayout(FRGUIPaneFactory.createBorderLayout()); boundPane = new WidgetBoundPane(creator); - this.add(boundPane, BorderLayout.NORTH); - + if (!DesignerUIModeConfig.getInstance().newUIMode()){ + this.add(boundPane, BorderLayout.NORTH); + } JPanel panel1 = FRGUIPaneFactory.createBorderLayout_S_Pane(); this.add(panel1, BorderLayout.CENTER); @@ -118,12 +124,13 @@ public class FRAbsoluteBodyLayoutDefinePane extends FRAbsoluteLayoutDefinePane { UILabel layoutTypeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")); UILabel scaleModeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode")); - - JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane( - new Component[][]{ - {layoutTypeLabel, layoutCombox}, - {scaleModeLabel, comboBox} - }, + Component[][] components = DesignerUIModeConfig.getInstance().newUIMode() ? new Component[][]{ + {layoutTypeLabel, layoutCombox} + } : new Component[][]{ + {layoutTypeLabel, layoutCombox}, + {scaleModeLabel, comboBox} + }; + JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(components, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); contentPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); @@ -173,12 +180,24 @@ public class FRAbsoluteBodyLayoutDefinePane extends FRAbsoluteLayoutDefinePane { ((XWFitLayout) creator.getBackupParent()).toData().resetStyle(); if (state == WBodyLayoutType.FIT.getTypeValue()) { XWFitLayout xwFitLayout = ((XWFitLayout)creator.getBackupParent()); - xwFitLayout.switch2FitBodyLayout(creator); - WFitLayout wFitLayout = xwFitLayout.toData(); - // 切换布局类型时,保留body背景样式 - if (wFitLayout != null) { - wFitLayout.setBorderStyleFollowingTheme(layout.isBorderStyleFollowingTheme()); - wFitLayout.setBorderStyle(layout.getBorderStyle()); + int selVal = FineJOptionPane.showConfirmDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Form_Layout_Switch_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Alert"), + OK_CANCEL_OPTION, + WARNING_MESSAGE + ); + if(OK_OPTION == selVal){ + xwFitLayout.switch2FitBodyLayout(creator); + WFitLayout wFitLayout = xwFitLayout.toData(); + // 切换布局类型时,保留body背景样式 + if (wFitLayout != null) { + wFitLayout.setBorderStyleFollowingTheme(layout.isBorderStyleFollowingTheme()); + wFitLayout.setBorderStyle(layout.getBorderStyle()); + } + copyLayoutAttr(layout, xwFitLayout.toData()); + }else { + this.layoutCombox.setSelectedIndex(1); } copyLayoutAttr(layout, xwFitLayout.toData()); xwFitLayout.refreshStylePreviewEffect(); diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteLayoutDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteLayoutDefinePane.java index dff0e159a..ef82a81b6 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteLayoutDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteLayoutDefinePane.java @@ -5,6 +5,7 @@ import com.fr.design.designer.IntervalConstants; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.properties.items.FRAbsoluteConstraintsItems; import com.fr.design.designer.properties.items.Item; +import com.fr.design.fit.DesignerUIModeConfig; import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.ilable.UILabel; @@ -39,7 +40,9 @@ public class FRAbsoluteLayoutDefinePane extends AbstractFRLayoutDefinePane 0 && ((XCreator) xCreator.getComponent(0)).shouldScaleCreator()) { - component = xCreator.getComponent(0); + Component component = xCreator.getComponent(0); component.setBounds(xCreator.getBounds()); } } - xwAbsoluteBodyLayout.add(component); + if (!xCreator.acceptType(XOccupiedLayout.class)){ + xwAbsoluteBodyLayout.add(xCreator); + } + } copyLayoutAttr(wFitLayout, xwAbsoluteBodyLayout.toData()); xWFitLayout.setBackupParent(xwAbsoluteBodyLayout); FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); formDesigner.getSelectionModel().setSelectedCreators( FormSelectionUtils.rebuildSelection(xWFitLayout, new Widget[]{wAbsoluteBodyLayout})); - if (xwAbsoluteBodyLayout.toData() != null) { xwAbsoluteBodyLayout.toData().setBorderStyleFollowingTheme(wAbsoluteBodyLayout.isBorderStyleFollowingTheme()); xwAbsoluteBodyLayout.toData().setBorderStyle(wAbsoluteBodyLayout.getBorderStyle()); @@ -254,6 +281,8 @@ public class FRFitLayoutDefinePane extends AbstractFRLayoutDefinePane + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/2.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/2.frm new file mode 100644 index 000000000..0b04d5e7d --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/2.frm @@ -0,0 +1,128 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/3.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/3.frm new file mode 100644 index 000000000..43cc0b93b --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/3.frm @@ -0,0 +1,137 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/4.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/4.frm new file mode 100644 index 000000000..d6b0ba42b --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/4.frm @@ -0,0 +1,137 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/5.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/5.frm new file mode 100644 index 000000000..167db8fd2 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/5.frm @@ -0,0 +1,137 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/6.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/6.frm new file mode 100644 index 000000000..504bfbd12 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/6.frm @@ -0,0 +1,137 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/1.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/1.frm new file mode 100644 index 000000000..24df43d5c --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/1.frm @@ -0,0 +1,146 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/2.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/2.frm new file mode 100644 index 000000000..e7f9d76d0 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/2.frm @@ -0,0 +1,146 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/3.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/3.frm new file mode 100644 index 000000000..1b1f1e1a4 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/3.frm @@ -0,0 +1,155 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/4.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/4.frm new file mode 100644 index 000000000..dcd003aa1 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/4.frm @@ -0,0 +1,155 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/5.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/5.frm new file mode 100644 index 000000000..98a3ac6f9 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/5.frm @@ -0,0 +1,164 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/6.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/6.frm new file mode 100644 index 000000000..34d579ed5 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/6.frm @@ -0,0 +1,164 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/1.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/1.frm new file mode 100644 index 000000000..710ccc3bd --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/1.frm @@ -0,0 +1,173 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/2.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/2.frm new file mode 100644 index 000000000..2bfe6c198 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/2.frm @@ -0,0 +1,182 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/3.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/3.frm new file mode 100644 index 000000000..e80cd4303 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/3.frm @@ -0,0 +1,182 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/4.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/4.frm new file mode 100644 index 000000000..21eac8ae6 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/4.frm @@ -0,0 +1,182 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/5.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/5.frm new file mode 100644 index 000000000..21c56152f --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/5.frm @@ -0,0 +1,191 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/6.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/6.frm new file mode 100644 index 000000000..a76dbdb6b --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/6.frm @@ -0,0 +1,209 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-realize/src/main/java/com/fr/design/actions/report/ReportEngineAttrAction.java b/designer-realize/src/main/java/com/fr/design/actions/report/ReportEngineAttrAction.java index 8dd00d170..4c7feab06 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/report/ReportEngineAttrAction.java +++ b/designer-realize/src/main/java/com/fr/design/actions/report/ReportEngineAttrAction.java @@ -1,14 +1,13 @@ package com.fr.design.actions.report; - -import com.fr.base.svg.IconUtils; import com.fr.design.actions.ReportComponentAction; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.WorkSheetDesigner; import com.fr.design.menu.KeySetUtils; -import com.fr.design.report.LayerReportPane; +import com.fr.design.report.ReportEnginePane; import com.fr.report.worksheet.WorkSheet; public class ReportEngineAttrAction extends ReportComponentAction { @@ -19,7 +18,7 @@ public class ReportEngineAttrAction extends ReportComponentAction { button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); - TemplateThemeUsingDialog dialog = new TemplateThemeUsingDialog<>(designerFrame, JWorkBook.this, ReportThemeConfig.getInstance()); + TemplateThemeUsingDialog dialog = new TemplateThemeUsingDialog(); dialog.setVisible(true); } }); @@ -716,8 +717,13 @@ public class JWorkBook extends JTemplate { } protected void addShortCut(MenuDef exportMenuDef, MenuDef excelExportMenuDef) { - exportMenuDef.addShortCut(excelExportMenuDef, new PDFExportAction(this), new WordExportAction(this), new SVGExportAction(this), - new CSVExportAction(this), new TextExportAction(this), new EmbeddedExportExportAction(this)); + if (CptAndCptxCompatibilityUtil.isEngineXEnable(this.getTarget(), getEditingFILE().getPath())){ + exportMenuDef.addShortCut(excelExportMenuDef, new PDFExportAction(this), new WordExportAction(this), new SVGExportAction(this), + new CSVExportAction(this), new TextExportAction(this)); + }else { + exportMenuDef.addShortCut(excelExportMenuDef, new PDFExportAction(this), new WordExportAction(this), new SVGExportAction(this), + new CSVExportAction(this), new TextExportAction(this), new EmbeddedExportExportAction(this)); + } } /** @@ -741,7 +747,8 @@ public class JWorkBook extends JTemplate { */ @Override public ShortCut[] shortcut4TemplateMenu() { - return ArrayUtils.addAll(new ShortCut[]{ + boolean enableNewEngine = CptAndCptxCompatibilityUtil.isEngineXEnable(this.getTarget(), getEditingFILE().getPath()); + ShortCut[] commonShortCut = ArrayUtils.addAll(new ShortCut[]{ new ReportWebAttrAction(this), new ReportExportAttrAction(this), new ReportParameterAction(this), @@ -751,8 +758,15 @@ public class JWorkBook extends JTemplate { new ReportWatermarkAction(this), new NameSeparator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Utils_Current_Sheet")), }, this.reportComposite.getEditingReportComponent().shortcut4TemplateMenu()); + if (enableNewEngine){ + return ArraysUtil.insert(commonShortCut, new CalculateAttrAction(this), 5); + }else { + return commonShortCut; + } } + + /** * 模板的工具 * @@ -1232,7 +1246,6 @@ public class JWorkBook extends JTemplate { protected void addChooseFILEFilter(FILEChooserPane fileChooser) { String appName = ProductConstants.APP_NAME; fileChooser.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CPT, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); - fileChooser.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CPTX, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); addExtraChooseFILEFilter(fileChooser); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java b/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java index b412d724d..5fe561829 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java @@ -34,7 +34,7 @@ public class ReportComponentComposite extends JComponent implements RemoveListen private static final int MAX = 400; private static final int HUND = 100; private static final int MIN = 10; - private static final int DIR = 10; + public static final int DIR = 10; private JWorkBook parent; private UIModeControlContainer parentContainer = null; @@ -66,17 +66,6 @@ public class ReportComponentComposite extends JComponent implements RemoveListen jSliderContainer.addValueChangeListener(showValSpinnerChangeListener); } - MouseWheelListener showValSpinnerMouseWheelListener = new MouseWheelListener() { - @Override - public void mouseWheelMoved(MouseWheelEvent e) { - if (InputEventBaseOnOS.isControlDown(e)) { - int dir = e.getWheelRotation(); - int old_resolution = jSliderContainer.getShowValue(); - jSliderContainer.setShowValue(old_resolution - (dir * DIR)); - } - } - }; - ChangeListener showValSpinnerChangeListener = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { @@ -130,12 +119,12 @@ public class ReportComponentComposite extends JComponent implements RemoveListen } if (centerCardPane.editingComponet.elementCasePane == null) { - centerCardPane.getPolyDezi().polyArea.addMouseWheelListener(showValSpinnerMouseWheelListener); + centerCardPane.getPolyDezi().polyArea.addMouseWheelListener(new ReportComponentCompositeMouseWheelHandler(this)); return; } Grid grid = centerCardPane.editingComponet.elementCasePane.getGrid(); - this.centerCardPane.editingComponet.elementCasePane.getGrid().addMouseWheelListener(showValSpinnerMouseWheelListener); + this.centerCardPane.editingComponet.elementCasePane.getGrid().addMouseWheelListener(new ReportComponentCompositeMouseWheelHandler(this)); if (!grid.hasFocus() && grid.isRequestFocusEnabled()) { grid.requestFocus(); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentCompositeMouseWheelHandler.java b/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentCompositeMouseWheelHandler.java new file mode 100644 index 000000000..e8b41afac --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentCompositeMouseWheelHandler.java @@ -0,0 +1,75 @@ +package com.fr.design.mainframe; + +import com.fr.common.inputevent.InputEventBaseOnOS; + +import javax.swing.JScrollBar; +import javax.swing.JViewport; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/24 + */ +public class ReportComponentCompositeMouseWheelHandler implements MouseWheelListener { + private final DesignerTranslateMouseWheelHandler translateMouseWheelHandler; + private final DesignerScaleMouseWheelHandler scaleMouseWheelHandler; + + public ReportComponentCompositeMouseWheelHandler(ReportComponentComposite componentComposite) { + translateMouseWheelHandler = new DesignerTranslateMouseWheelHandler(new ScrollPaneAdapter(componentComposite)); + scaleMouseWheelHandler = new DesignerScaleMouseWheelHandler(new ScalePaneAdapter(componentComposite), ReportComponentComposite.DIR); + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if (InputEventBaseOnOS.isControlDown(e)) { + scaleMouseWheelHandler.mouseWheelMoved(e); + } else { + translateMouseWheelHandler.mouseWheelMoved(e); + } + } + + private static class ScrollPaneAdapter implements DesignerTranslateMouseWheelHandler.ScrollPane { + private final ReportComponentComposite componentComposite; + private JViewport viewport; + + public ScrollPaneAdapter(ReportComponentComposite componentComposite) { + this.componentComposite = componentComposite; + this.viewport = new JViewport(); + } + + @Override + public boolean isWheelScrollingEnabled() { + return true; + } + + @Override + public JScrollBar getVerticalScrollBar() { + return componentComposite.getEditingReportComponent().getVerticalScrollBar(); + } + + @Override + public JScrollBar getHorizontalScrollBar() { + return componentComposite.getEditingReportComponent().getHorizontalScrollBar(); + } + + @Override + public JViewport getViewport() { + return viewport; + } + } + + private static class ScalePaneAdapter implements DesignerScaleMouseWheelHandler.ScalePane { + private final ReportComponentComposite componentComposite; + + public ScalePaneAdapter(ReportComponentComposite componentComposite) { + this.componentComposite = componentComposite; + } + + @Override + public JFormSliderPane getSlidePane() { + return componentComposite.getjSliderContainer(); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java index e7612c001..47c2e6c7e 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java @@ -32,19 +32,17 @@ import com.fr.design.mainframe.alphafine.search.manager.impl.RecentSearchManager import com.fr.design.mainframe.alphafine.search.manager.impl.RecommendSearchManager; import com.fr.design.mainframe.alphafine.search.manager.impl.SegmentationManager; import com.fr.design.mainframe.alphafine.search.manager.impl.SimilarSearchManager; -import com.fr.form.main.Form; -import com.fr.form.main.FormIO; import com.fr.general.ComparatorUtils; import com.fr.general.http.HttpClient; -import com.fr.io.TemplateWorkBookIO; -import com.fr.io.exporter.ImageExporter; import com.fr.json.JSONObject; import com.fr.log.FineLoggerFactory; -import com.fr.main.impl.WorkBook; import com.fr.stable.CodeUtils; import com.fr.stable.StringUtils; import com.fr.stable.project.ProjectConstants; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.exporter.LocalExportOperator; +import com.fr.workspace.server.exporter.TemplateExportOperator; import javax.imageio.ImageIO; import javax.swing.BorderFactory; import javax.swing.DefaultListModel; @@ -601,14 +599,15 @@ public class AlphaFineDialog extends UIDialog { checkWorker(); this.showWorker = new SwingWorker() { @Override - protected BufferedImage doInBackground() { - Form form = null; + protected BufferedImage doInBackground() throws Exception { + byte[] bytes = null; try { - form = FormIO.readForm(fileName); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + bytes = WorkContext.getCurrent().get(TemplateExportOperator.class).exportFormAsImageData(fileName); + } catch (Exception ignored) { + // 兼容下老版本 + bytes = new LocalExportOperator().exportFormAsImageData(fileName); } - return FormIO.exportFormAsImage(form); + return TemplateExportOperator.byteDataToImage(bytes); } @Override @@ -631,15 +630,15 @@ public class AlphaFineDialog extends UIDialog { checkWorker(); this.showWorker = new SwingWorker() { @Override - protected BufferedImage doInBackground() { - WorkBook workBook = null; + protected BufferedImage doInBackground() throws Exception { + byte[] bytes = null; try { - workBook = (WorkBook) TemplateWorkBookIO.readTemplateWorkBook(fileName); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + bytes = WorkContext.getCurrent().get(TemplateExportOperator.class).exportWorkBookAsImageData(fileName); + } catch (Exception ignored) { + // 兼容下老版本 + bytes = new LocalExportOperator().exportWorkBookAsImageData(fileName); } - BufferedImage bufferedImage = new ImageExporter().exportToImage(workBook); - return bufferedImage; + return TemplateExportOperator.byteDataToImage(bytes); } @Override diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoLabel.java b/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoLabel.java index 29180c09d..3ba44743d 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoLabel.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoLabel.java @@ -6,6 +6,7 @@ package com.fr.design.mainframe.bbs; import com.fr.design.DesignerEnvManager; import com.fr.design.bbs.BBSLoginUtils; import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.FineJOptionPane; import com.fr.design.extra.LoginContextListener; import com.fr.design.extra.UserLoginContext; import com.fr.design.gui.ilable.UILabel; @@ -14,6 +15,7 @@ import com.fr.design.gui.imenu.UIPopupMenu; import com.fr.design.locale.impl.BbsSpaceMark; import com.fr.design.login.DesignerLoginHelper; import com.fr.design.login.DesignerLoginSource; +import com.fr.design.login.service.DesignerPassportManager; import com.fr.design.login.utils.DesignerLoginUtils; import com.fr.design.mainframe.DesignerContext; import com.fr.design.os.impl.SupportOSImpl; @@ -29,6 +31,7 @@ import com.fr.general.locale.LocaleMark; import com.fr.log.FineLoggerFactory; import com.fr.stable.EncodeConstants; import com.fr.stable.StringUtils; +import javax.swing.JOptionPane; import javax.swing.SwingConstants; import java.awt.Cursor; import java.awt.Frame; @@ -120,8 +123,33 @@ public class UserInfoLabel extends UILabel { UserLoginContext.fireLoginContextListener(DesignerLoginSource.SWITCH_ACCOUNT); } }); + //退出登录 + UIMenuItem logout = new UIMenuItem(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_BBSLogin_Logout")); + logout.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + String[] options = new String[]{ + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_BBSLogin_Logout"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Button_Cancel") + }; + int rv = FineJOptionPane.showConfirmDialog( + DesignerLoginHelper.getDialog(), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_BBSLogin_Logout_Tip"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + JOptionPane.OK_CANCEL_OPTION, + JOptionPane.WARNING_MESSAGE, + null, + options, + options[1] + ); + if (rv == JOptionPane.YES_OPTION) { + DesignerPassportManager.getInstance().logout(); + } + } + }); menu.add(priviteMessage); menu.add(closeOther); + menu.add(logout); GUICoreUtils.showPopupMenu(menu, UserInfoLabel.this, 0, MENU_HEIGHT); } else { UserLoginContext.fireLoginContextListener(DesignerLoginSource.NORMAL); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoPane.java index e6ae079aa..b3d6e35e5 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoPane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoPane.java @@ -86,6 +86,12 @@ public class UserInfoPane extends BasicPane { markSignIn(text); } }); + EventDispatcher.listen(CertificateEvent.LOGOUT, new Listener() { + @Override + public void on(Event event, String text) { + markUnSignIn(); + } + }); } public UserInfoLabel getUserInfoLabel() { diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java index 1d02fde9c..bcf1244d3 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java @@ -27,7 +27,8 @@ import com.fr.report.cell.cellattr.CellInsertPolicyAttr; import com.fr.report.cell.cellattr.CellPageAttr; import com.fr.report.elementcase.TemplateElementCase; import com.fr.stable.StringUtils; - +import com.fr.design.i18n.Toolkit; +import java.awt.Color; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JPanel; @@ -75,6 +76,11 @@ public class CellOtherSetPane extends AbstractCellAttrPane { private UICheckBox canBreakOnPaginateCheckBox; private UICheckBox repeatCheckBox; + //固定行数分页 + private UICheckBox pageFixedRowDataCheckBox; + private UILabel currentPageFixedRowDataTipLabel; + private TemplateCellElement pageFixedRowDataCell; + // 自动调整 private UIRadioButton autoHeightRadioButton; // 自动调整行高 private UIRadioButton autoWidthRadioButton; // 自动调整列宽 @@ -90,6 +96,7 @@ public class CellOtherSetPane extends AbstractCellAttrPane { private JPanel insertRowPolicyPane; private JPanel defaultValuePane; + private static final Color TIPS_FONT_COLOR = new Color(0x8f8f92); /** * 初始化 * @@ -263,8 +270,10 @@ public class CellOtherSetPane extends AbstractCellAttrPane { pageBeforeColumnCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_Page_Before_Column")); pageAfterColumnCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_Page_After_Column")); - canBreakOnPaginateCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellPage_Can_Break_On_Paginate")); - repeatCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellPage_Repeat_Content_When_Paging")); + canBreakOnPaginateCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_CellPage_Can_Break_On_Paginate")); + repeatCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_CellPage_Repeat_Content_When_Paging")); + pageFixedRowDataCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_CellWrite_Page_Fixed_Row_Cell")); + currentPageFixedRowDataTipLabel = new UILabel(" (" + Toolkit.i18nText("Fine-Design_Report_CellWrite_No_Page_Fixed_Row_Cell") +")"); pageBeforeRowCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); pageAfterRowCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); @@ -272,11 +281,13 @@ public class CellOtherSetPane extends AbstractCellAttrPane { pageAfterColumnCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); canBreakOnPaginateCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); repeatCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); - + pageFixedRowDataCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); + currentPageFixedRowDataTipLabel.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); + currentPageFixedRowDataTipLabel.setForeground(TIPS_FONT_COLOR); double p = TableLayout.PREFERRED; - double[] rowSize = {p, p, p, p, p, p, p, p, p, p, p}; + double[] rowSize = {p, p, p, p, p, p, p, p, p, p, p,p}; double[] columnSize = {p}; - int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},{1,1},{1,1}}; Component[][] components = new Component[][]{ new Component[]{null}, new Component[]{pageBeforeRowCheckBox}, @@ -287,6 +298,9 @@ public class CellOtherSetPane extends AbstractCellAttrPane { new Component[]{null}, new Component[]{canBreakOnPaginateCheckBox}, new Component[]{repeatCheckBox}, + new Component[]{null}, + new Component[]{pageFixedRowDataCheckBox}, + new Component[]{currentPageFixedRowDataTipLabel} }; return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.VGAP_MEDIUM, LayoutConstants.VGAP_LARGE); @@ -345,6 +359,7 @@ public class CellOtherSetPane extends AbstractCellAttrPane { repeatCheckBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellPage_Repeat_Content_When_Paging")); insertRowPolicyButtonGroup.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_InsertRow_Policy")); valueEditor.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_InsertRow_Policy")); + pageFixedRowDataCheckBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_Page_Fixed_Row_Cell")); } @@ -356,6 +371,9 @@ public class CellOtherSetPane extends AbstractCellAttrPane { @Override protected void populateBean() { + this.currentPageFixedRowDataTipLabel.setText(" (" + Toolkit.i18nText("Fine-Design_Report_CellWrite_No_Page_Fixed_Row_Cell") + ")"); + this.pageFixedRowDataCell = null; + checkPageFixedRow(); CellGUIAttr cellGUIAttr = cellElement.getCellGUIAttr(); if (cellGUIAttr == null) { cellGUIAttr = CellGUIAttr.DEFAULT_CELLGUIATTR; @@ -411,6 +429,7 @@ public class CellOtherSetPane extends AbstractCellAttrPane { this.pageAfterColumnCheckBox.setSelected(cellPageAttr.isPageAfterColumn()); this.canBreakOnPaginateCheckBox.setSelected(cellPageAttr.isCanBreakOnPaginate()); this.repeatCheckBox.setSelected(cellPageAttr.isRepeat()); + this.pageFixedRowDataCheckBox.setSelected(cellPageAttr.isPageFixedRow()); CellInsertPolicyAttr cellInsertPolicyAttr = cellElement.getCellInsertPolicyAttr();// 插入 if (cellInsertPolicyAttr == null) { cellInsertPolicyAttr = new CellInsertPolicyAttr(); @@ -536,6 +555,20 @@ public class CellOtherSetPane extends AbstractCellAttrPane { cellPageAttr.setRepeat(this.repeatCheckBox.isSelected()); } + if (ComparatorUtils.equals(getGlobalName(), Toolkit.i18nText("Fine-Design_Report_CellWrite_Page_Fixed_Row_Cell"))) { + cellPageAttr.setPageFixedRow(this.pageFixedRowDataCheckBox.isSelected()); + if (this.pageFixedRowDataCheckBox.isSelected()) { + if (pageFixedRowDataCell != null && pageFixedRowDataCell != cellElement) { + pageFixedRowDataCell.getCellPageAttr().setPageFixedRow(false); + } + pageFixedRowDataCell = cellElement; + currentPageFixedRowDataTipLabel.setText(" (" + Toolkit.i18nText("Fine-Design_Report_CellWrite_Current_Page_Fixed_Row_Cell") + cellElement.toString() + ")"); + } else { + if (pageFixedRowDataCell != null && pageFixedRowDataCell == cellElement) { + currentPageFixedRowDataTipLabel.setText(" (" + Toolkit.i18nText("Fine-Design_Report_CellWrite_No_Page_Fixed_Row_Cell") + ")"); + } + } + } cellElement.setCellPageAttr(cellPageAttr); if (ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_InsertRow_Policy"))) { @@ -579,6 +612,29 @@ public class CellOtherSetPane extends AbstractCellAttrPane { } } + private void checkPageFixedRow() { + TemplateElementCase elementCase = elementCasePane.getEditingElementCase(); + int rowCount = elementCase.getRowCount(); + int columnCount = elementCase.getColumnCount(); + boolean find = false; + for (int row = 0; row < rowCount; row++) { + for (int column = 0; column < columnCount; column++) { + TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); + if (cellElement != null) { + if (cellElement.getCellPageAttr() != null && cellElement.getCellPageAttr().isPageFixedRow()) { + this.pageFixedRowDataCell = cellElement; + this.currentPageFixedRowDataTipLabel.setText(" (" + Toolkit.i18nText("Fine-Design_Report_CellWrite_Current_Page_Fixed_Row_Cell") + cellElement.toString() + ")"); + find = true; + break; + } + } + } + if (find) { + break; + } + } + } + /** * 返回界面的标题 * diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/CustomStylePane.java b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/CustomStylePane.java index 268dbebe6..302cc45b7 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/CustomStylePane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/CustomStylePane.java @@ -151,7 +151,7 @@ public class CustomStylePane extends MultiTabPane