diff --git a/build.gradle b/build.gradle index 5bac80b64..a3892da96 100644 --- a/build.gradle +++ b/build.gradle @@ -69,6 +69,7 @@ allprojects { implementation 'org.swingexplorer:swag:1.0' implementation 'net.java.dev.jna:jna:5.4.0' implementation 'org.apache.tomcat:tomcat-catalina:8.5.72' + implementation 'org.apache.tomcat:tomcat-websocket:8.5.72' implementation 'io.socket:socket.io-client:0.7.0' implementation 'com.fr.third:fine-third:' + frVersion implementation 'com.fr.core:fine-core:' + frDevVersion diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java index f65610526..38d287a20 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java @@ -1,12 +1,12 @@ package com.fr.design.data.datapane; import com.fr.base.TableData; -import com.fr.concurrent.NamedThreadFactory; import com.fr.data.core.DataCoreUtils; import com.fr.data.core.db.DBUtils; import com.fr.data.core.db.TableProcedure; import com.fr.data.core.db.dialect.Dialect; import com.fr.data.core.db.dialect.DialectFactory; +import com.fr.data.impl.Connection; import com.fr.data.impl.DBTableData; import com.fr.data.operator.DataOperator; import com.fr.design.DesignerEnvManager; @@ -19,7 +19,7 @@ import com.fr.design.data.datapane.preview.PreviewTablePane; import com.fr.design.data.tabledata.Prepare4DataSourceChange; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.icombobox.FilterableComboBoxModel; -import com.fr.design.gui.icombobox.SearchPreTaskTreeComboBox; +import com.fr.design.gui.icombobox.SearchFRTreeComboBox; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.icombobox.UIComboBoxEditor; import com.fr.design.gui.icombobox.UIComboBoxRenderer; @@ -40,11 +40,6 @@ import com.fr.stable.StringUtils; import com.fr.workspace.WorkContext; import com.fr.workspace.server.connection.DBConnectAuth; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Dimension; -import java.util.Collections; -import java.util.concurrent.CancellationException; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -58,21 +53,20 @@ import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeCellRenderer; -import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.Collection; -import java.util.Enumeration; +import java.util.Collections; import java.util.List; import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.FutureTask; +import java.util.concurrent.CancellationException; /** * @author zhou @@ -97,41 +91,12 @@ public class ChoosePane extends BasicBeanPane implements Refresha /** * 表名 */ - protected SearchPreTaskTreeComboBox tableNameComboBox; - - private static final ExecutorService SERVICE = Executors.newSingleThreadExecutor(new NamedThreadFactory("ChoosePane")); + protected SearchFRTreeComboBox tableNameComboBox; private SwingWorker populateWorker; private SwingWorker, Void> initWorker; - private PopupMenuListener popupMenuListener = new PopupMenuListener() { - - @Override - public void popupMenuWillBecomeVisible(PopupMenuEvent e) { - FutureTask task = new FutureTask(new Callable() { - @Override - public Void call() throws Exception { - calculateTableDataNames(); - return null; - } - }); - tableNameComboBox.setPreSearchTask(task); - SERVICE.submit(task); - } - - @Override - public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { - // Do nothing - } - - @Override - public void popupMenuCanceled(PopupMenuEvent e) { - // Do nothing - } - }; - - private PopupMenuListener listener = new PopupMenuListener() { @Override public void popupMenuCanceled(PopupMenuEvent e) { @@ -181,7 +146,7 @@ public class ChoosePane extends BasicBeanPane implements Refresha schemaBox = new StringUIComboBox(); schemaBox.setEditor(new ComboBoxEditor()); - tableNameComboBox = new SearchPreTaskTreeComboBox(new JTree(new DefaultMutableTreeNode()), tableNameTreeRenderer, false); + tableNameComboBox = new SearchFRTreeComboBox(this, new JTree(new DefaultMutableTreeNode()), tableNameTreeRenderer); tableNameComboBox.setEditable(true); tableNameComboBox.setRenderer(listCellRenderer); registerDSChangeListener(); @@ -198,7 +163,6 @@ public class ChoosePane extends BasicBeanPane implements Refresha }); schemaBox.addPopupMenuListener(listener); addFocusListener(); - this.tableNameComboBox.addPopupMenuListener(popupMenuListener); } protected void addDSBoxListener() { @@ -355,7 +319,7 @@ public class ChoosePane extends BasicBeanPane implements Refresha GUICoreUtils.setSelectedItemQuietly(tableNameComboBox, -1); } - protected com.fr.data.impl.Connection getConnection() { + public Connection getConnection() { String selectedDSName = this.getDSName(); if (StringUtils.isEmpty(selectedDSName)) { return null; // peter:选中了当前的零长度的节点,直接返回. @@ -455,56 +419,6 @@ public class ChoosePane extends BasicBeanPane implements Refresha return "choosepane"; } - protected void calculateTableDataNames() { - JTree tree = tableNameComboBox.getTree(); - if (tree == null) { - return; - } - DefaultMutableTreeNode rootTreeNode = (DefaultMutableTreeNode) tree.getModel().getRoot(); - rootTreeNode.removeAllChildren(); - - String selectedDSName = this.getDSName(); - com.fr.data.impl.Connection selectedDatabase = this.getConnection(); - if (selectedDatabase == null) { - return; - } - try { - String schema = StringUtils.isEmpty(this.schemaBox.getSelectedItem()) ? null : this.schemaBox.getSelectedItem(); - TableProcedure[] sqlTableArray = DataCoreUtils.getTables(selectedDatabase, TableProcedure.TABLE, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace()); - if (sqlTableArray.length > 0) { - ExpandMutableTreeNode tableTreeNode = new ExpandMutableTreeNode(selectedDSName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_Table")); - rootTreeNode.add(tableTreeNode); - for (int i = 0; i < sqlTableArray.length; i++) { - ExpandMutableTreeNode tableChildTreeNode = new ExpandMutableTreeNode(sqlTableArray[i]); - tableTreeNode.add(tableChildTreeNode); - } - } - TableProcedure[] sqlViewArray = DataCoreUtils.getTables(selectedDatabase, TableProcedure.VIEW, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace()); - if (sqlViewArray.length > 0) { - ExpandMutableTreeNode viewTreeNode = new ExpandMutableTreeNode(selectedDSName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_View")); - rootTreeNode.add(viewTreeNode); - for (int i = 0; i < sqlViewArray.length; i++) { - ExpandMutableTreeNode viewChildTreeNode = new ExpandMutableTreeNode(sqlViewArray[i]); - viewTreeNode.add(viewChildTreeNode); - } - } - ((DefaultTreeModel) tree.getModel()).reload(); - // daniel 展开所有tree - TreeNode root = (TreeNode) tree.getModel().getRoot(); - TreePath parent = new TreePath(root); - TreeNode node = (TreeNode) parent.getLastPathComponent(); - for (Enumeration e = node.children(); e.hasMoreElements(); ) { - TreeNode n = (TreeNode) e.nextElement(); - TreePath path = parent.pathByAddingChild(n); - tree.expandPath(path); - } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Failed"), JOptionPane.ERROR_MESSAGE); - } - } - /** * 创建选中的数据集数据 * @@ -558,10 +472,14 @@ public class ChoosePane extends BasicBeanPane implements Refresha return tableData; } - protected String getDSName() { + public String getDSName() { return this.dsNameComboBox.getSelectedItem(); } + public String getSchema() { + return this.schemaBox.getSelectedItem(); + } + protected void failedToFindTable() { // Do nothing } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePaneSupportFormula.java b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePaneSupportFormula.java index 14d0431e2..8fc62cd77 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePaneSupportFormula.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePaneSupportFormula.java @@ -83,7 +83,7 @@ public class ChoosePaneSupportFormula extends ChoosePane { * * @return */ - protected String getDSName() { + public String getDSName() { String selectedDSName = null; String item = Utils.objectToString(this.dsNameComboBox.getEditor().getItem()); // 没有选中的列表项 那么看看是不是手输值 diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java index 2b0df3447..91e8006d1 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java @@ -14,6 +14,7 @@ import com.fr.data.solution.processor.SolutionProcessor; import com.fr.design.beans.BasicBeanPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.ActionLabel; import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; @@ -33,6 +34,7 @@ import javax.swing.JDialog; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; +import javax.swing.ScrollPaneConstants; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import javax.swing.UIManager; @@ -59,6 +61,8 @@ import java.util.concurrent.ExecutionException; * Database Connection pane. */ public abstract class DatabaseConnectionPane extends BasicBeanPane { + private static int MAX_MAIN_PANEL_HEIGHT = 430; + private static int MAX_MAIN_PANEL_WIDTH = 675; private UILabel message; private UIButton okButton; @@ -333,11 +337,11 @@ public abstract class DatabaseConnectionPane MAX_MAIN_PANEL_HEIGHT || mainPanel.getPreferredSize().width > MAX_MAIN_PANEL_WIDTH) { + UIScrollPane jp = new + UIScrollPane(mainPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + jp.setPreferredSize(new Dimension(MAX_MAIN_PANEL_WIDTH, MAX_MAIN_PANEL_HEIGHT)); + northPane.add(jp, BorderLayout.CENTER); + } else { + mainPanel.setPreferredSize(new Dimension(MAX_MAIN_PANEL_WIDTH, MAX_MAIN_PANEL_HEIGHT)); + northPane.add(mainPanel, BorderLayout.CENTER); + } // ChartSet String[] defaultEncode = new String[]{Toolkit.i18nText("Fine-Design_Encode_Auto")}; charSetComboBox = new UIComboBox(ArrayUtils.addAll(defaultEncode, EncodeConstants.ENCODING_ARRAY)); diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java index 8fe79d41e..c12239447 100644 --- a/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java +++ b/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java @@ -248,7 +248,7 @@ public class FRTreeComboBox extends UIComboBox { private static TreePopup treePopup; - private static class FRTreeComboBoxUI extends BasicComboBoxUI implements MouseListener{ + protected static class FRTreeComboBoxUI extends BasicComboBoxUI implements MouseListener{ private boolean isRollover = false; public FRTreeComboBoxUI() { @@ -535,7 +535,7 @@ public class FRTreeComboBox extends UIComboBox { public class FrTreeSearchComboBoxEditor extends UIComboBoxEditor implements DocumentListener { private volatile boolean setting = false; private FRTreeComboBox comboBox; - private Object item; + protected Object item; public FrTreeSearchComboBoxEditor(FRTreeComboBox comboBox) { super(); diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchFRTreeComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchFRTreeComboBox.java new file mode 100644 index 000000000..06f50e211 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchFRTreeComboBox.java @@ -0,0 +1,200 @@ +package com.fr.design.gui.icombobox; + +import com.fr.data.core.DataCoreUtils; +import com.fr.data.core.db.TableProcedure; +import com.fr.data.impl.Connection; +import com.fr.design.DesignerEnvManager; +import com.fr.design.data.datapane.ChoosePane; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; +import com.fr.design.mainframe.DesignerContext; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; +import com.fr.stable.StringUtils; + +import javax.swing.JOptionPane; +import javax.swing.JTree; +import javax.swing.SwingWorker; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.awt.event.MouseEvent; +import java.util.Enumeration; + +/** + * 实现模糊搜索的FRTreeComboBox + * FRTreeComboBox:搜索后滚动到首个匹配节点 + * SearchFRTreeComboBox:显示所有匹配的节点 + * + * @author Lucian.Chen + * @version 10.0 + * Created by Lucian.Chen on 2021/4/14 + */ +public class SearchFRTreeComboBox extends FRTreeComboBox { + + // 持有父容器,需要实时获取其他组件值 + private final ChoosePane parent; + + public SearchFRTreeComboBox(ChoosePane parent, JTree tree, TreeCellRenderer renderer) { + super(tree, renderer); + this.parent = parent; + setUI(new SearchFRTreeComboBoxUI()); + } + + protected UIComboBoxEditor createEditor() { + return new SearchFRComboBoxEditor(this); + } + + /** + * 执行模糊搜索 + */ + private void searchExecute() { + UIComboBoxEditor searchEditor = (UIComboBoxEditor) this.getEditor(); + new SwingWorker() { + @Override + protected Void doInBackground() { + processTableDataNames( + parent.getDSName(), + parent.getConnection(), + parent.getSchema(), + createFilter((String) searchEditor.getItem())); + return null; + } + + @Override + protected void done() { + expandTree(); + // 输入框获取焦点 + searchEditor.getEditorComponent().requestFocus(); + } + }.execute(); + } + + private TableNameFilter createFilter(String text) { + return StringUtils.isEmpty(text) ? EMPTY_FILTER : new TableNameFilter(text); + } + + /** + * 查询数据库表,并构建节点目录 + * + * @param databaseName 数据库名 + * @param connection 数据连接 + * @param schema 模式 + * @param filter 模糊搜索过滤器 + */ + private void processTableDataNames(String databaseName, Connection connection, String schema, TableNameFilter filter) { + if (tree == null) { + return; + } + DefaultMutableTreeNode rootTreeNode = (DefaultMutableTreeNode) tree.getModel().getRoot(); + rootTreeNode.removeAllChildren(); + + if (connection == null) { + return; + } + try { + schema = StringUtils.isEmpty(schema) ? null : schema; + TableProcedure[] sqlTableArray = DataCoreUtils.getTables(connection, TableProcedure.TABLE, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace()); + if (ArrayUtils.isNotEmpty(sqlTableArray)) { + ExpandMutableTreeNode tableTreeNode = new ExpandMutableTreeNode(databaseName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_Table")); + rootTreeNode.add(tableTreeNode); + addArrayNode(tableTreeNode, sqlTableArray, filter); + } + TableProcedure[] sqlViewArray = DataCoreUtils.getTables(connection, TableProcedure.VIEW, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace()); + if (ArrayUtils.isNotEmpty(sqlViewArray)) { + ExpandMutableTreeNode viewTreeNode = new ExpandMutableTreeNode(databaseName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_View")); + rootTreeNode.add(viewTreeNode); + addArrayNode(viewTreeNode, sqlViewArray, filter); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Failed"), JOptionPane.ERROR_MESSAGE); + } + } + + private void addArrayNode(ExpandMutableTreeNode rootNode, TableProcedure[] sqlArray, TableNameFilter filter) { + if (sqlArray != null) { + for (TableProcedure procedure : sqlArray) { + if (filter.accept(procedure)) { + ExpandMutableTreeNode viewChildTreeNode = new ExpandMutableTreeNode(procedure); + rootNode.add(viewChildTreeNode); + } + } + } + } + + /** + * 展开节点 + */ + private void expandTree() { + ((DefaultTreeModel) tree.getModel()).reload(); + // daniel 展开所有tree + TreeNode root = (TreeNode) tree.getModel().getRoot(); + TreePath parent = new TreePath(root); + TreeNode node = (TreeNode) parent.getLastPathComponent(); + for (Enumeration e = node.children(); e.hasMoreElements(); ) { + TreeNode n = (TreeNode) e.nextElement(); + TreePath path = parent.pathByAddingChild(n); + tree.expandPath(path); + } + } + + /** + * 重写输入框编辑器,实现输入框模糊搜索逻辑 + */ + private class SearchFRComboBoxEditor extends FrTreeSearchComboBoxEditor { + + public SearchFRComboBoxEditor(FRTreeComboBox comboBox) { + super(comboBox); + } + + @Override + protected void changeHandler() { + if (isSetting()) { + return; + } + setPopupVisible(true); + this.item = textField.getText(); + searchExecute(); + } + } + + private static final TableNameFilter EMPTY_FILTER = new TableNameFilter(StringUtils.EMPTY) { + public boolean accept(TableProcedure procedure) { + return true; + } + }; + + /** + * 表名模糊搜索实现 + */ + private static class TableNameFilter { + private final String searchFilter; + + public TableNameFilter(String searchFilter) { + if (StringUtils.isNotEmpty(searchFilter)) { + searchFilter = searchFilter.toLowerCase().trim(); + } + this.searchFilter = searchFilter; + } + + // 字符串匹配 + public boolean accept(TableProcedure procedure) { + return procedure.getName().toLowerCase().contains(searchFilter); + } + } + + /** + * 重写FRTreeComboBoxUI,实现点击下拉时触发模糊搜索 + */ + private class SearchFRTreeComboBoxUI extends FRTreeComboBoxUI { + + @Override + public void mouseClicked(MouseEvent e) { + searchExecute(); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java deleted file mode 100644 index 2d936d896..000000000 --- a/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.fr.design.gui.icombobox; - -import com.fr.log.FineLoggerFactory; - -import javax.swing.JTree; -import javax.swing.SwingWorker; -import javax.swing.tree.TreeCellRenderer; -import java.util.concurrent.FutureTask; - -/** - * 模糊搜索前需执行完前置任务的TreeComboBox - * @author Lucian.Chen - * @version 10.0 - * Created by Lucian.Chen on 2021/4/14 - */ -public class SearchPreTaskTreeComboBox extends FRTreeComboBox { - - /** - * 模糊搜索前任务 - */ - private FutureTask preSearchTask; - - public SearchPreTaskTreeComboBox(JTree tree, TreeCellRenderer renderer, boolean editable) { - super(tree, renderer, editable); - } - - public FutureTask getPreSearchTask() { - return preSearchTask; - } - - public void setPreSearchTask(FutureTask preSearchTask) { - this.preSearchTask = preSearchTask; - } - - protected UIComboBoxEditor createEditor() { - return new SearchPreTaskComboBoxEditor(this); - } - - private class SearchPreTaskComboBoxEditor extends FrTreeSearchComboBoxEditor { - - public SearchPreTaskComboBoxEditor(FRTreeComboBox comboBox) { - super(comboBox); - } - - protected void changeHandler() { - if (isSetting()) { - return; - } - setPopupVisible(true); - new SwingWorker() { - @Override - protected Void doInBackground() { - FutureTask task = getPreSearchTask(); - try { - // 确保模糊搜索前任务执行完成后,再进行模糊搜索 - if (task != null) { - task.get(); - } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - if (task != null) { - // 任务执行后置空,否则会被别的操作重复触发 - setPreSearchTask(null); - } - return null; - } - - @Override - protected void done() { - // 模糊搜索 - search(); - } - }.execute(); - } - } -} 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 index fbe63218e..7e0db6051 100644 --- 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 @@ -372,10 +372,20 @@ public class TextFormatPane extends AbstractBasicStylePane implements GlobalName * 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 updateByGlobalNamedSetting(style); + } + + private Style updateByGlobalNamedSetting(Style style) { + if (globalNameListener != null) { + String[] alterSettingNames = new String[] {"typeComboBox", "textField", "roundingBox"}; + String globalSettingName = globalNameListener.getGlobalName(); + if (StringUtils.isNotEmpty(globalSettingName)) { + for (String alterSettingName : alterSettingNames) { + if (ComparatorUtils.equals(alterSettingName, globalSettingName)) { + return style.deriveFormat(this.update()); + } + } + } } return style; } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java index 9e8ffd792..bcda18bb6 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java @@ -221,10 +221,14 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt if (success) { FileNode fileNode = TemplateTreePane.getInstance().getFileNode(); refreshRightToolBarBy(fileNode); - TemplateTreePane.getInstance().refresh(); } else { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Template_Unlock_Failed"), + Toolkit.i18nText("Fine-Design_Basic_Alert"), + JOptionPane.WARNING_MESSAGE); FineLoggerFactory.getLogger().error("Unlock {} failed", path); } + TemplateTreePane.getInstance().refresh(); } } }); diff --git a/designer-form/src/main/java/com/fr/design/fit/DesignerUIModeConfig.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerUIModeConfig.java similarity index 65% rename from designer-form/src/main/java/com/fr/design/fit/DesignerUIModeConfig.java rename to designer-base/src/main/java/com/fr/design/mainframe/DesignerUIModeConfig.java index 5e743d383..1e072d956 100644 --- a/designer-form/src/main/java/com/fr/design/fit/DesignerUIModeConfig.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerUIModeConfig.java @@ -1,19 +1,16 @@ -package com.fr.design.fit; +package com.fr.design.mainframe; import com.fr.base.ScreenResolution; import com.fr.design.fun.ReportLengthUNITProvider; import com.fr.design.unit.UnitConvertUtil; import com.fr.general.ComparatorUtils; -import com.fr.general.FRScreen; import com.fr.stable.Constants; -import java.awt.Dimension; - /** * Created by kerry on 2020-06-05 */ public class DesignerUIModeConfig { - private DesignerUIMode mode = DesignerUIMode.NEW_UI_MODE; + private DesignerUIMode mode = DesignerUIMode.ABSOLUTE_MEASURE_UI_MODE; private static class DesignerUIModeConfigHolder { private static final DesignerUIModeConfig designerUIModeConfig = new DesignerUIModeConfig(); @@ -33,22 +30,22 @@ public class DesignerUIModeConfig { * * @return boolean */ - public boolean newUIMode() { - return ComparatorUtils.equals(DesignerUIMode.NEW_UI_MODE, mode); + public boolean simulateWebUIMode() { + return ComparatorUtils.equals(DesignerUIMode.SIMULATE_WEB_UI_MODE, mode); } /** * 设置新ui模式 */ - public void setNewUIMode() { - this.mode = DesignerUIMode.NEW_UI_MODE; + public void setSimulateWebUIMode() { + this.mode = DesignerUIMode.SIMULATE_WEB_UI_MODE; } /** * 设置老ui模式 */ - public void setOldUIMode() { - this.mode = DesignerUIMode.OLD_UI_MODE; + public void setAbsoluteMeasureUIMode() { + this.mode = DesignerUIMode.ABSOLUTE_MEASURE_UI_MODE; } /** @@ -70,55 +67,38 @@ public class DesignerUIModeConfig { return mode.getScreenResolution(); } - /** - * 根据屏幕尺寸获取设计时的FRScreen - * - * @param screen 屏幕尺寸 - * @return FRScreen - */ - public FRScreen getDesignScreenByDimension(Dimension screen) { - return mode.getDesignScreenByDimension(screen); - } private enum DesignerUIMode { - OLD_UI_MODE { + ABSOLUTE_MEASURE_UI_MODE { @Override protected ReportLengthUNITProvider parseLengthUNIT(int unitType) { return UnitConvertUtil.parseLengthUNIT(unitType); } - @Override - protected FRScreen getDesignScreenByDimension(Dimension screen) { - return FRScreen.getDesignScreenByDimension(screen); - } - @Override protected int getScreenResolution() { return ScreenResolution.getScreenResolution(); } + }, - NEW_UI_MODE { + SIMULATE_WEB_UI_MODE { @Override protected ReportLengthUNITProvider parseLengthUNIT(int unitType) { return new PXReportLengthUNIT(); } - @Override - protected FRScreen getDesignScreenByDimension(Dimension screen) { - return FRScreen.p1440; - } - @Override protected int getScreenResolution() { return Constants.DEFAULT_WEBWRITE_AND_SCREEN_RESOLUTION; } + }; protected abstract ReportLengthUNITProvider parseLengthUNIT(int unitType); - protected abstract FRScreen getDesignScreenByDimension(Dimension screen); protected abstract int getScreenResolution(); + } } 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 a08febe68..26a2f64bc 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 @@ -1869,4 +1869,8 @@ public abstract class JTemplate> } + public void setDesignerUIMode(){ + DesignerUIModeConfig.getInstance().setAbsoluteMeasureUIMode(); + } + } \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/fit/PX.java b/designer-base/src/main/java/com/fr/design/mainframe/PX.java similarity index 94% rename from designer-form/src/main/java/com/fr/design/fit/PX.java rename to designer-base/src/main/java/com/fr/design/mainframe/PX.java index 720268ea6..8fd9ac0ed 100644 --- a/designer-form/src/main/java/com/fr/design/fit/PX.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/PX.java @@ -1,4 +1,4 @@ -package com.fr.design.fit; +package com.fr.design.mainframe; import com.fr.stable.Constants; import com.fr.stable.unit.LEN_UNIT; diff --git a/designer-form/src/main/java/com/fr/design/fit/PXReportLengthUNIT.java b/designer-base/src/main/java/com/fr/design/mainframe/PXReportLengthUNIT.java similarity index 95% rename from designer-form/src/main/java/com/fr/design/fit/PXReportLengthUNIT.java rename to designer-base/src/main/java/com/fr/design/mainframe/PXReportLengthUNIT.java index 8d8f1de16..69d46480e 100644 --- a/designer-form/src/main/java/com/fr/design/fit/PXReportLengthUNIT.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/PXReportLengthUNIT.java @@ -1,4 +1,4 @@ -package com.fr.design.fit; +package com.fr.design.mainframe; import com.fr.design.fun.impl.AbstractReportLengthUNITProvider; import com.fr.stable.unit.UNIT; 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 c3ba368a3..172ac3c3f 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 @@ -1,5 +1,7 @@ package com.fr.design.mainframe.theme.edit.cell; +import com.fr.base.CellBorderStyle; +import com.fr.base.Style; import com.fr.base.theme.settings.ThemedCellStyle; import com.fr.design.cell.CellRectangleStylePreviewPane; import com.fr.design.constants.UIConstants; @@ -87,12 +89,35 @@ public class CellStyleEditPane extends MultiTabPane { @Override public ThemedCellStyle updateBean() { AbstractBasicStylePane basicStylePane = (AbstractBasicStylePane) paneList.get(tabPane.getSelectedIndex()); - this.cellStyle.setStyle(basicStylePane.update(this.cellStyle.getStyle())); + Style style = basicStylePane.update(this.cellStyle.getStyle()); + CellBorderStyle borderStyle = createDefaultBorderStyleFromStyle(style); + + if (ThemedFeatureController.isCellStyleSupportInnerBorder() && basicStylePane instanceof BorderPane) { - this.cellStyle.setCellBorderStyle(((BorderPane) basicStylePane).update()); + borderStyle = ((BorderPane) basicStylePane).update(); } + + this.cellStyle.setStyle(style); + this.cellStyle.setCellBorderStyle(borderStyle); + return this.cellStyle; } + private CellBorderStyle createDefaultBorderStyleFromStyle(Style style) { + CellBorderStyle cellBorderStyle = new CellBorderStyle(); + cellBorderStyle.setTopStyle(style.getBorderTop()); + cellBorderStyle.setTopColor(style.getBorderTopColor()); + + cellBorderStyle.setBottomStyle(style.getBorderBottom()); + cellBorderStyle.setBottomColor(style.getBorderBottomColor()); + + cellBorderStyle.setLeftStyle(style.getBorderLeft()); + cellBorderStyle.setLeftColor(style.getBorderLeftColor()); + + cellBorderStyle.setRightStyle(style.getBorderRight()); + cellBorderStyle.setRightColor(style.getBorderRightColor()); + + return cellBorderStyle; + } @Override public boolean accept(Object ob) { @@ -117,8 +142,10 @@ public class CellStyleEditPane extends MultiTabPane { JPanel previewPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); previewArea = new CellRectangleStylePreviewPane(true); - previewArea.setPreferredSize(new Dimension(223, 60)); - previewPane.setBorder(BorderUtils.createTitleBorder(i18nText("Fine-Design_Basic_Preview"))); + previewArea.setPreferredSize(new Dimension(215, 52)); + previewPane.setBorder(BorderFactory.createCompoundBorder( + BorderUtils.createTitleBorder(i18nText("Fine-Design_Basic_Preview")), + BorderFactory.createEmptyBorder(4, 4, 4, 4))); previewPane.add(previewArea, BorderLayout.CENTER); this.add(previewPane, BorderLayout.NORTH); diff --git a/designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java b/designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java index 854d260bf..35e2090d9 100644 --- a/designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java +++ b/designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java @@ -8,8 +8,10 @@ import com.fr.stable.EncodeConstants; import com.fr.stable.ProductConstants; import com.fr.stable.StringUtils; import com.fr.startup.FineWebApplicationInitializer; +import com.fr.third.guava.collect.Sets; import com.fr.third.springframework.web.SpringServletContainerInitializer; import com.fr.third.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import com.fr.web.socketio.WebSocketEndpoint; import com.fr.workspace.WorkContext; import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; @@ -17,6 +19,7 @@ import org.apache.catalina.Wrapper; import org.apache.catalina.loader.WebappLoader; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.webresources.StandardRoot; +import org.apache.tomcat.websocket.server.WsSci; import java.io.File; import java.util.HashSet; @@ -92,6 +95,7 @@ public class FineEmbedServerActivator extends Activator { Set> classes = new HashSet>(); classes.add(FineWebApplicationInitializer.class); context.addServletContainerInitializer(initializer, classes); + context.addServletContainerInitializer(new WsSci(), Sets.newHashSet(WebSocketEndpoint.class)); } // tomcat的maxPostSize会影响到post参数获取,默认2M diff --git a/designer-form/src/main/java/com/fr/design/actions/NewFormMobileAttrAction.java b/designer-form/src/main/java/com/fr/design/actions/NewFormMobileAttrAction.java deleted file mode 100644 index 17ec76b83..000000000 --- a/designer-form/src/main/java/com/fr/design/actions/NewFormMobileAttrAction.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.fr.design.actions; - - -import com.fr.base.iofile.attr.MobileOnlyTemplateAttrMark; -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.dialog.BasicDialog; -import com.fr.design.dialog.DialogActionAdapter; -import com.fr.design.fit.NewJForm; -import com.fr.design.fit.common.AdaptiveSwitchUtil; -import com.fr.design.fit.common.TemplateTool; -import com.fr.design.form.mobile.FormMobileAttrPane; -import com.fr.design.mainframe.DesignerContext; -import com.fr.design.mainframe.FormArea; -import com.fr.design.mainframe.FormDesigner; -import com.fr.design.mainframe.JForm; -import com.fr.design.mainframe.WidgetPropertyPane; -import com.fr.file.FILE; -import com.fr.form.main.Form; -import com.fr.form.main.mobile.FormMobileAttr; -import com.fr.record.analyzer.EnableMetrics; -import com.fr.stable.StringUtils; - -import java.awt.event.ActionEvent; - -/** - * Created by fanglei on 2016/11/14. - */ -@EnableMetrics -public class NewFormMobileAttrAction extends FormMobileAttrAction { - - public NewFormMobileAttrAction(JForm jf) { - super(jf); - } - - /** - * 执行动作 - * - * @return 是否执行成功 - */ - @Override - public void actionPerformed(ActionEvent e) { - final JForm jf = getEditingComponent(); - if (jf == null) { - return; - } - final Form formTpl = jf.getTarget(); - FormMobileAttr mobileAttr = formTpl.getFormMobileAttr(); - - final FormMobileAttrPane mobileAttrPane = new FormMobileAttrPane(); - mobileAttrPane.populateBean(mobileAttr); - - final boolean oldMobileOnly = mobileAttr.isMobileOnly(); - final boolean oldAdaptive = mobileAttr.isAdaptivePropertyAutoMatch(); - BasicDialog dialog = mobileAttrPane.showWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { - @Override - public void doOk() { - FormMobileAttr formMobileAttr = mobileAttrPane.updateBean(); - if (formMobileAttr.isMobileOnly() && jf.getTarget().getAttrMark(MobileOnlyTemplateAttrMark.XML_TAG) == null) { - // 如果是老模板,选择手机专属之后需要另存为 - FILE editingFILE = jf.getEditingFILE(); - if (editingFILE != null && editingFILE.exists()) { - String fileName = editingFILE.getName().substring(0, editingFILE.getName().length() - jf.suffix().length()) + "_mobile"; - if (!jf.saveAsTemplate(true, fileName)) { - return; - } - } - // 放到后面。如果提前 return 了,则仍然处于未设置状态,不要添加 - jf.getTarget().addAttrMark(new MobileOnlyTemplateAttrMark()); - } - // 设置移动端属性并刷新界面 - formTpl.setFormMobileAttr(formMobileAttr); // 会调整 body 的自适应布局,放到最后 - boolean changeSize = (!oldMobileOnly && formMobileAttr.isMobileOnly()) || (oldMobileOnly && !formMobileAttr.isMobileOnly()); - if (changeSize) { - ((FormArea)jf.getFormDesign().getParent()).onMobileAttrModified(); - } - //改变布局为自适应布局,只在移动端属性设置保存后改变一次 - boolean changeLayout = !oldAdaptive && formMobileAttr.isAdaptivePropertyAutoMatch(); - if (changeLayout) { - jf.getFormDesign().getSelectionModel().setSelectedCreator(jf.getFormDesign().getRootComponent()); - doChangeBodyLayout(); - WidgetPropertyPane.getInstance().refreshDockingView(); - } - jf.fireTargetModified(); - FILE editingFILE = jf.getEditingFILE(); - if(editingFILE != null && editingFILE.exists()){ - JForm jForm = getEditingComponent(); - TemplateTool.saveForm(jForm); - if (jForm instanceof NewJForm) { - AdaptiveSwitchUtil.switch2OldUI(); - } - }else { - AdaptiveSwitchUtil.switch2OldUIMode(); - NewJForm mobileJForm = new NewJForm(jf.getTarget(), jf.getEditingFILE()); - //设置临时的id,和新建的模板区分 - mobileJForm.getTarget().setTemplateID(StringUtils.EMPTY); - TemplateTool.resetTabPaneEditingTemplate(mobileJForm); - TemplateTool.activeAndResizeTemplate(mobileJForm); - } - } - }); - dialog.setVisible(true); - } - - private void doChangeBodyLayout(){ - FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - XLayoutContainer rootLayout = formDesigner.getRootComponent(); - if (rootLayout.getComponentCount() == 1 && rootLayout.getXCreator(0).acceptType(XWAbsoluteBodyLayout.class)) { - rootLayout = (XWAbsoluteBodyLayout) rootLayout.getXCreator(0); - } - ((XWFitLayout)formDesigner.getRootComponent()).switch2FitBodyLayout(rootLayout); - } -} - diff --git a/designer-form/src/main/java/com/fr/design/fit/JFormType.java b/designer-form/src/main/java/com/fr/design/fit/JFormType.java index f2d1c4ad9..52c8f728c 100644 --- a/designer-form/src/main/java/com/fr/design/fit/JFormType.java +++ b/designer-form/src/main/java/com/fr/design/fit/JFormType.java @@ -1,30 +1,10 @@ package com.fr.design.fit; -import com.fr.design.beans.BasicBeanPane; -import com.fr.design.fit.common.AdaptiveSwitchUtil; -import com.fr.form.fit.NewFormMarkAttr; import com.fr.form.fit.config.FormFitConfig; -import com.fr.design.fit.menupane.FormFitAttrPane; -import com.fr.design.fun.PreviewProvider; -import com.fr.design.mainframe.JTemplate; -import com.fr.design.preview.FormAdaptivePreview; -import com.fr.design.preview.FormPreview; -import com.fr.design.report.fit.menupane.ReportFitAttrPane; -import com.fr.form.main.Form; import com.fr.report.fit.ReportFitAttr; public enum JFormType { - OLD_TYPE(0, new FormPreview()) { - @Override - public void switchUI() { - AdaptiveSwitchUtil.switch2OldUI(); - } - - @Override - public void switchUIMode() { - AdaptiveSwitchUtil.switch2OldUIMode(); - } - + OLD_TYPE(0) { @Override public ReportFitAttr obtainFitAttr() { return FormFitConfig.getInstance().getOldFitAttr(); @@ -35,23 +15,9 @@ public enum JFormType { FormFitConfig.getInstance().setOldFitAttr(attr); } - @Override - public BasicBeanPane obtainAttrPane(NewJForm newJForm) { - return new ReportFitAttrPane(); - } }, - NEW_TYPE(1, new FormAdaptivePreview()) { - @Override - public void switchUI() { - AdaptiveSwitchUtil.switch2NewUI(); - } - - @Override - public void switchUIMode() { - AdaptiveSwitchUtil.switch2NewUIMode(); - } - + NEW_TYPE(1) { @Override public ReportFitAttr obtainFitAttr() { return FormFitConfig.getInstance().getNewFitAttr(); @@ -62,80 +28,35 @@ public enum JFormType { FormFitConfig.getInstance().setNewFitAttr(attr); } - @Override - public BasicBeanPane obtainAttrPane(NewJForm newJForm) { - return new FormFitAttrPane(newJForm); - } }; - private int type; - private boolean newType; - private PreviewProvider defaultPreviewType; + private final int type; + private final boolean newType; - JFormType(int type, PreviewProvider defaultPreviewType) { + JFormType(int type) { this.type = type; this.newType = (type == 1); - this.defaultPreviewType = defaultPreviewType; } public int getType() { return type; } - public boolean isNewType() { - return newType; - } - public PreviewProvider getDefaultPreviewType() { - return defaultPreviewType; + public static JFormType parseFormType(int type) { + for (JFormType formType : values()) { + if (formType.getType() == type) { + return formType; + } + } + return JFormType.OLD_TYPE; } - public abstract void switchUI(); - - public abstract void switchUIMode(); + public boolean isNewType() { + return newType; + } public abstract ReportFitAttr obtainFitAttr(); public abstract void updateFitAttr(ReportFitAttr attr); - public abstract BasicBeanPane obtainAttrPane(NewJForm newJForm); - - /** - * @Description: 更新模板的标志位 - * @param jTemplate - * @return: - * @Author: Henry.Wang - * @date: 2020/12/17 16:17 - */ - public void updateJFromTemplateType(JTemplate jTemplate) { - if (jTemplate instanceof NewJForm) { - NewJForm newJForm = (NewJForm) jTemplate; - Form form = newJForm.getTarget(); - NewFormMarkAttr newFormMarkAttr = form.getAttrMark(NewFormMarkAttr.XML_TAG); - if (newFormMarkAttr == null) { - newFormMarkAttr = new NewFormMarkAttr(this.getType()); - form.addAttrMark(newFormMarkAttr); - } - newFormMarkAttr.setType(this.getType()); - newJForm.setJFormType(this); - } - } - - /** - * @Description: 更新预览方式 - * @param jTemplate - * @return: - * @Author: Henry.Wang - * @date: 2020/12/17 16:17 - */ - public void updatePreviewType(JTemplate jTemplate) { - if (jTemplate.getPreviewType() != null) { - PreviewProvider[] previewProviders = jTemplate.supportPreview(); - for (PreviewProvider previewProvider : previewProviders) { - if (previewProvider.getClass() == jTemplate.getPreviewType().getClass()) { - return; - } - } - } - jTemplate.setPreviewType(this.getDefaultPreviewType()); - } } 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 2445b45e5..9df0806de 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 @@ -2,19 +2,18 @@ package com.fr.design.fit; import com.fr.base.DynamicUnitList; import com.fr.base.Parameter; -import com.fr.design.actions.TemplateParameterAction; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.LayoutAdapter; import com.fr.design.designer.beans.adapters.layout.FRFitLayoutAdapter; import com.fr.design.designer.beans.events.DesignerEditListener; import com.fr.design.designer.beans.events.DesignerEvent; -import com.fr.design.actions.NewFormMobileAttrAction; import com.fr.design.designer.creator.XComponent; import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XElementCase; import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWTitleLayout; import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.preview.DeveloperPreview; import com.fr.design.preview.FormAdaptivePreview; import com.fr.design.fit.toolbar.SwitchAction; @@ -22,12 +21,12 @@ import com.fr.design.fun.PreviewProvider; import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.JForm; import com.fr.design.mainframe.WidgetPropertyPane; -import com.fr.design.menu.ShortCut; import com.fr.design.preview.FormPreview; import com.fr.design.preview.MobilePreview; import com.fr.design.utils.ComponentUtils; import com.fr.file.FILE; import com.fr.form.FormElementCaseProvider; +import com.fr.form.fit.NewFormMarkAttr; import com.fr.form.main.Form; import com.fr.form.ui.ElementCaseEditor; import com.fr.stable.ArrayUtils; @@ -53,6 +52,8 @@ public class NewJForm extends JForm { public NewJForm(Form form) { super(form); init(); + //新建的模板都要加上新表单标志attr + form.addAttrMark(NewFormMarkAttr.createNewFormAttr()); } public NewJForm(Form form, FILE file, Parameter[] parameters) { @@ -61,9 +62,7 @@ public class NewJForm extends JForm { public NewJForm(Form form, FILE file) { super(form, file); - if (DesignerUIModeConfig.getInstance().newUIMode()) { - init(); - } + init(); } public JFormType getJFormType() { @@ -74,22 +73,6 @@ public class NewJForm extends JForm { this.jFormType = jFormType; } - - /** - * 模板菜单 - * - * @return 返回菜单 - */ - @Override - public ShortCut[] shortcut4TemplateMenu() { - if (this.index == FORM_TAB) { - return ArrayUtils.addAll(new ShortCut[]{new TemplateParameterAction(this), new NewFormMobileAttrAction(this), getReportFitAttrAction()}, new ShortCut[0]); - } else { - return ArrayUtils.addAll(new ShortCut[]{new TemplateParameterAction(this), new NewFormMobileAttrAction(this), getReportFitAttrAction()}, this.getElementCaseDesign().shortcut4TemplateMenu()); - } - } - - private void init() { this.getFormDesign().addDesignerEditListener(new DesignerEditListener() { private Rectangle oldRec; @@ -202,6 +185,13 @@ public class NewJForm extends JForm { } }); + + Form form = this.getTarget(); + NewFormMarkAttr newFormMarkAttr = form.getAttrMark(NewFormMarkAttr.XML_TAG); + if (newFormMarkAttr == null) { + newFormMarkAttr = new NewFormMarkAttr(); + } + this.setJFormType(JFormType.parseFormType(newFormMarkAttr.getType())); } @@ -225,16 +215,14 @@ public class NewJForm extends JForm { return new PreviewProvider[]{new FormPreview(), new MobilePreview()}; } - private SwitchAction switchAction; - public UIButton[] createExtraButtons() { UIButton[] extraButtons = super.createExtraButtons(); return addAdaptiveSwitchButton(extraButtons); } private UIButton[] addAdaptiveSwitchButton(UIButton[] extraButtons) { - switchAction = new SwitchAction(); - return ArrayUtils.addAll(extraButtons, new UIButton[]{switchAction.getToolBarButton()}); + SwitchAction switchAction = new SwitchAction(this); + return ArrayUtils.addAll(extraButtons, switchAction.getToolBarButton()); } public boolean isNewJFrom() { 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 3d090d8f1..031d69849 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 @@ -1,15 +1,14 @@ 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.mainframe.DesignerContext; -import com.fr.design.mainframe.JForm; import com.fr.design.mainframe.JTemplate; import com.fr.design.preview.FormAdaptivePreview; import com.fr.design.preview.FormPreview; import com.fr.file.FILE; import com.fr.file.MemFILE; +import com.fr.form.fit.NewFormMarkAttr; import com.fr.form.main.Form; import com.fr.form.main.WidgetGather; import com.fr.form.ui.Widget; @@ -33,25 +32,10 @@ public class AdaptiveSwitchUtil { } - public static void switch2NewUI() { - switch2NewUIMode(); - reload(); - } - - public static void switch2NewUIMode() { - DesignerUIModeConfig.getInstance().setNewUIMode(); - } - - public static void switch2OldUI() { - switch2OldUIMode(); - reload(); - } - - public static void switch2OldUIMode() { - DesignerUIModeConfig.getInstance().setOldUIMode(); - } - - public static void reload() { + /** + * 新老表单转换的方法 + */ + public static void switchReload() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { @@ -61,15 +45,15 @@ public class AdaptiveSwitchUtil { return; } JTemplate old = TemplateTool.getCurrentEditingTemplate(); - if (!(old instanceof JForm)) { + if (!(old instanceof NewJForm)) { return; } - JTemplate template = createNewJTemplate(old); + JTemplate template = createNewJTemplate((NewJForm) old); if (template != null) { DesignTableDataManager.closeTemplate(old); TemplateTool.resetTabPaneEditingTemplate(template); TemplateTool.activeAndResizeTemplate(template); - setPreviewType(); + setPreviewType(template); } } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage()); @@ -83,14 +67,12 @@ public class AdaptiveSwitchUtil { /** * @Description: 设置预览方式 - * @return: 新创建的模板 * @Author: Henry.Wang * @date: 2020/10/13 14:08 */ - private static void setPreviewType() { - JTemplate jTemplate = TemplateTool.getCurrentEditingTemplate(); + private static void setPreviewType(JTemplate jTemplate) { if (jTemplate != null) { - if (DesignerUIModeConfig.getInstance().newUIMode()) { + if (TemplateTool.isNewJForm(jTemplate)) { jTemplate.setPreviewType(new FormAdaptivePreview()); } else { jTemplate.setPreviewType(new FormPreview()); @@ -99,29 +81,30 @@ public class AdaptiveSwitchUtil { } /** + * @param oldForm 以前的模板 * @Description: 创建模板 - * @param old 以前的模板 * @return: 新创建的模板 * @Author: Henry.Wang * @date: 2020/9/6 14:08 */ - public static JTemplate createNewJTemplate(JTemplate old) { - JTemplate template; - template = createNewJTemplateInternal(old); - if (template instanceof NewJForm) { - NewJForm jForm = ((NewJForm) template); - //如果是从旧的设计模板转化为新的设计模式,并且不是全局配置的模板。则更新新模板的Pc端自适应属性 - if (DesignerUIModeConfig.getInstance().newUIMode() && jForm.getTarget().getReportFitAttr() != null && isSwitchJFromIng()) { - jForm.getTarget().setReportFitAttr(shiftReportFitAttr(old, jForm.getTarget().getReportFitAttr().isFitFont())); - } - processAbsoluteLayoutCompatible(jForm.getTarget()); - TemplateTool.saveForm(jForm); + public static JTemplate createNewJTemplate(NewJForm oldForm) { + NewJForm newJForm = createNewJTemplateInternal(oldForm); + if (newJForm == null) { + return null; + } + //如果是从旧的设计模板转化为新的设计模式,并且不是全局配置的模板。则更新新模板的Pc端自适应属性 + if (newJForm.getTarget().getReportFitAttr() != null && newJForm.isNewJFrom()) { + //修改自适应属性 + newJForm.getTarget().setReportFitAttr(shiftReportFitAttr(oldForm, newJForm.getTarget().getReportFitAttr().isFitFont())); + //修改绝对布局中的缩放属性 + processAbsoluteLayoutCompatible(newJForm.getTarget()); } - return template; + TemplateTool.saveForm(newJForm); + return newJForm; } - private static void processAbsoluteLayoutCompatible(Form form){ + private static void processAbsoluteLayoutCompatible(Form form) { Form.traversalWidget(form.getContainer(), new WidgetGather() { @Override public void dealWith(Widget widget) { @@ -141,22 +124,28 @@ public class AdaptiveSwitchUtil { } - /** - * @Description: 创建模板核心方法 * @param old 以前的方法 + * @Description: 创建模板核心方法 * @return: 新创建的模板 * @Author: Henry.Wang * @date: 2020/9/6 14:09 */ - private static JTemplate createNewJTemplateInternal(JTemplate old) { + private static NewJForm createNewJTemplateInternal(JTemplate old) { FILE file = old.getEditingFILE(); if ((file instanceof MemFILE) || !old.isSaved()) { TemplateTool.saveForm(old); } if (old.getTarget() instanceof Form) { try { - return new NewJForm((Form) (old.getTarget()).clone(), old.getEditingFILE()); + //这边进行数据模型中的标志位切换 + Form form = (Form) old.getTarget().clone(); + NewFormMarkAttr oldFormAttr = form.getAttrMark(NewFormMarkAttr.XML_TAG); + if (oldFormAttr == null) { + oldFormAttr = new NewFormMarkAttr(); + } + form.addAttrMark(oldFormAttr.switchAttr()); + return new NewJForm(form, old.getEditingFILE()); } catch (Exception e) { FineLoggerFactory.getLogger().error(e, e.getMessage()); return null; @@ -167,46 +156,43 @@ public class AdaptiveSwitchUtil { } /** - * @Description: 老模板切换到新模板的属性配置转换( - * 1、绝对布局-适应区域--》双向自适应 - * 2、自适应布局-双向自适应--》双向自适应 - * 3、自适应布局-横向自适应--》横向自适应 - * 4、绝对布局-固定大小--》不自适应 - * ) * @param old * @param fitFont 字体是否自适应 + * @Description: 老模板切换到新模板的属性配置转换( + * 1、绝对布局-适应区域--》双向自适应 + * 2、自适应布局-双向自适应--》双向自适应 + * 3、自适应布局-横向自适应--》横向自适应 + * 4、绝对布局-固定大小--》不自适应 + * ) * @return: * @Author: Henry.Wang * @date: 2020/9/6 14:01 */ - private static ReportFitAttr shiftReportFitAttr(JTemplate old, boolean fitFont) { - if (old instanceof JForm && DesignerUIModeConfig.getInstance().newUIMode()) { - JForm jForm = (JForm) old; - try { - int layoutType = LayoutTool.getFormLayoutType(jForm); - int compState = -1; - //自适应布局 - if (layoutType == 0) { - compState = ((WFitLayout) jForm.getFormDesign().getRootComponent().toData()).getCompState(); - if (compState == WFitLayout.STATE_FULL) { - return new ReportFitAttr(2, fitFont); - } else if (compState == WFitLayout.STATE_ORIGIN) { - return new ReportFitAttr(1, fitFont); - } - } else if (layoutType == 1) {//绝对布局 - Widget widget = ((CRBoundsWidget) jForm.getFormDesign().getRootComponent().toData().getWidget(0)).getWidget(); - if (widget instanceof WAbsoluteLayout) { - compState = ((WAbsoluteLayout) widget).getCompState(); - } - if (compState == WAbsoluteLayout.STATE_FIT) { - return new ReportFitAttr(2, fitFont); - } else if (compState == WAbsoluteLayout.STATE_FIXED) { - return new ReportFitAttr(3, fitFont); - } + private static ReportFitAttr shiftReportFitAttr(NewJForm old, boolean fitFont) { + try { + int layoutType = LayoutTool.getFormLayoutType(old); + int compState = -1; + //自适应布局 + if (layoutType == 0) { + compState = ((WFitLayout) old.getFormDesign().getRootComponent().toData()).getCompState(); + if (compState == WFitLayout.STATE_FULL) { + return new ReportFitAttr(2, fitFont); + } else if (compState == WFitLayout.STATE_ORIGIN) { + return new ReportFitAttr(1, fitFont); + } + } else if (layoutType == 1) {//绝对布局 + Widget widget = ((CRBoundsWidget) old.getFormDesign().getRootComponent().toData().getWidget(0)).getWidget(); + if (widget instanceof WAbsoluteLayout) { + compState = ((WAbsoluteLayout) widget).getCompState(); + } + if (compState == WAbsoluteLayout.STATE_FIT) { + return new ReportFitAttr(2, fitFont); + } else if (compState == WAbsoluteLayout.STATE_FIXED) { + return new ReportFitAttr(3, fitFont); } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); } return null; } diff --git a/designer-form/src/main/java/com/fr/design/fit/common/BaseUtils.java b/designer-form/src/main/java/com/fr/design/fit/common/BaseUtils.java deleted file mode 100644 index 829d320e8..000000000 --- a/designer-form/src/main/java/com/fr/design/fit/common/BaseUtils.java +++ /dev/null @@ -1,1266 +0,0 @@ -package com.fr.design.fit.common; - -import com.fr.base.AutoChangeLineAndDrawManager; -import com.fr.base.FRContext; -import com.fr.base.GraphHelper; -import com.fr.base.Style; -import com.fr.base.SynchronizedLiveDataModelUtils; -import com.fr.base.TableData; -import com.fr.base.regist.LicenseConfigManager; -import com.fr.config.ServerPreferenceConfig; -import com.fr.data.api.TableDataAssist; -import com.fr.design.fit.PX; -import com.fr.general.ComparatorUtils; -import com.fr.general.FArray; -import com.fr.general.FRFont; -import com.fr.general.GeneralContext; -import com.fr.general.GeneralUtils; -import com.fr.general.IOUtils; -import com.fr.general.data.DataModel; -import com.fr.general.data.TableDataException; -import com.fr.general.xml.GeneralXMLTools; -import com.fr.json.JSONArray; -import com.fr.json.JSONException; -import com.fr.json.JSONObject; -import com.fr.json.JSONUtils; -import com.fr.json.revise.EmbedJson; -import com.fr.locale.InterProviderFactory; -import com.fr.log.FineLoggerFactory; -import com.fr.plugin.injectable.PluginModule; -import com.fr.report.fun.VerticalTextProcessor; -import com.fr.report.fun.impl.DefaultVerticalTextProcessor; -import com.fr.script.Calculator; -import com.fr.stable.ColumnRow; -import com.fr.stable.Constants; -import com.fr.stable.GraphDrawHelper; -import com.fr.stable.ListSet; -import com.fr.stable.StableUtils; -import com.fr.stable.StringUtils; -import com.fr.stable.bridge.ObjectHolder; -import com.fr.stable.fun.AutoChangeLineAndDrawProcess; -import com.fr.stable.fun.FontProcessor; -import com.fr.stable.plugin.ExtraClassManagerProvider; -import com.fr.stable.project.ProjectConstants; -import com.fr.stable.script.CalculatorProvider; -import com.fr.stable.unit.FU; -import com.fr.stable.unit.UNIT; -import com.fr.workspace.WorkContext; - -import javax.swing.Icon; -import javax.swing.ImageIcon; -import javax.swing.JFrame; -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.Paint; -import java.awt.geom.AffineTransform; -import java.awt.geom.Dimension2D; -import java.awt.image.BufferedImage; -import java.awt.image.CropImageFilter; -import java.awt.image.FilteredImageSource; -import java.io.IOException; -import java.io.InputStream; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; - - -/** - * 基本的工具类 - */ -public class BaseUtils { - - private BaseUtils() { - } - - /** - * 从缓存中读取图片(如果缓存中存在的话则直接从缓存中读取,如果不存在则从磁盘读取并将读取的结果缓存起来) - * - * @param resource 图片的路径 - * @return 图片 - * @see IOUtils#readImageWithCache(String) - * @deprecated - */ - public static BufferedImage readImageWithCache(String resource) { - return IOUtils.readImageWithCache(resource); - } - - /** - * 从缓存中读取图片,如果缓存中不存在则返回null - * - * @param resource 图片路径 - * @return 图片,缓存中没有则返回null - * @see IOUtils#readCacheImage(String) - * @deprecated - */ - public static BufferedImage readCacheImage(String resource) { - return IOUtils.readCacheImage(resource); - } - - /** - * 直接从磁盘中读取图片,这种方法效率稍低但每次图片更改了也能即时反应出来 - * - * @param resource 图片的路径 - * @return 图片 - * @see IOUtils#readImage(String) - * @deprecated - */ - public static BufferedImage readImage(String resource) { - //daniel bug 5400 图片读取 默认关闭缓存 - return IOUtils.readImage(resource); - } - - /** - * 读取图标,该方法启用了缓存 - * - * @param resource 图标文件的存放路径 - * @return 图标 - * @see IOUtils#readIcon(String) - * @deprecated - */ - public static Icon readIcon(String resource) { - return IOUtils.readIcon(resource); - } - - /** - * 从输入流中读取图片 - * - * @param input 输入流 - * @return 图片 - * @throws IOException - * @see IOUtils#readImage(InputStream) - * @deprecated - */ - public static BufferedImage readImage(InputStream input) throws IOException { - return IOUtils.readImage(input); - } - - /** - * 将行列对象转换成其字符串的表示形式 - * 转换后的字符串将像A2,B4,C45这样的 - *

- * 将A1单元格转化成字符串"A1": - *

- * BaseUtils.convertColumnRowToCellString(ColumnRow.valueOf(0,0)); - * - * @param columnRow 要转换的行列对象 - * @return 表示行列位置的字符串 - */ - public static String convertColumnRowToCellString(ColumnRow columnRow) { - if (columnRow == null) { - return ""; - } - - return columnRow.toString(); - } - - /** - * 将表示行列位置的字符串转换成行列对象 - * 如果转换失败,将会返回{@link ColumnRow} - * - * @param columnRowString 表示行列位置的字符串对象 - * @return 行列对象 - * @see ColumnRow#valueOf(String) - * @deprecated - */ - public static ColumnRow convertCellStringToColumnRow(String columnRowString) { - return ColumnRow.valueOf(columnRowString); - } - - /** - * 读取jar的版本号 - * - * @return 版本号 - * @see GeneralUtils#readBuildNO() - * @deprecated - */ - public static String readBuildNO() { - return GeneralUtils.readBuildNO(); - } - - /** - * 把指定位置的资源以默认的GBK编码的形式读取成字符串 - * - * @param path 资源存放的路径 - * @return 表示资源内容的字符串 - * @see IOUtils#readResourceAsString(String) - * @deprecated - */ - public static String readResourceAsString(String path) { - return IOUtils.readResourceAsString(path); - } - - /** - * 将指定位置的资源以指定的编码形式读取成字符串 - * - * @param path 资源存放的路径 - * @param encode 读取资源所用的编码 - * @return 表示资源内容的字符串 - * @see IOUtils#readResourceAsString(String, String) - * @deprecated - */ - public static String readResourceAsString(String path, String encode) { - return IOUtils.readResourceAsString(path, encode); - } - - @Deprecated - public static String[] getDependence(Object value, CalculatorProvider c) { - - try { - return (String[]) StableUtils.invokeMethod("com.fr.form.FormUtils", "getDependence", new Class[]{Object.class, CalculatorProvider.class}, new Object[]{value, c}); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - return null; - } - - /** - * 读取资源 - * - * @param path 资源存放的路径,可以是一个URL - * @return 返回资源的输入流 - * @see IOUtils#readResource(String) - * @deprecated - */ - public static InputStream readResource(String path) { - return IOUtils.readResource(path); - } - - /** - * 截取图片的指定区域作为一个图标 - * - * @param image 原始的图片 - * @param startx 截取的横向起始位置 - * @param starty 截取的纵向起始位置 - * @param width 截取的图标的宽度 - * @param height 截取的图标的高度 - * @return 图标 - */ - public static ImageIcon createIcon(Image image, int startx, int starty, int width, int height) { - JFrame jc = new JFrame(); - Image cropImage = jc.createImage(new FilteredImageSource(image.getSource(), new CropImageFilter(startx, starty, width, height))); - return new ImageIcon(cropImage); - } - - /** - * 将一个长整形数组以指定的分隔符转化成一个字符串 - * - * @param array 数组 - * @param decimal 分隔符 - * @return 表示数组的字符串 - */ - public static String toLongArrayString(long[] array, char decimal) { - StringBuffer sb = new StringBuffer(); - if (array != null) { - for (int i = 0; i < array.length; i++) { - if (i != 0) { - sb.append(decimal); - } - sb.append(array[i]); - } - } - return sb.toString(); - } - - /** - * 将一个有规则的字符串按指定的分隔符分割并转化成一个长整型数组 - * - * @param str 有规则的字符串 - * @param decimal 分隔符 - * @return 长整型数组 - */ - public static long[] toLongArrayFromStr(String str, char decimal) { - List list = new ArrayList(); - if (str == null) { - return new long[0]; - } - String[] strarray = StableUtils.splitString(str, String.valueOf(decimal)); - for (int i = 0; i < strarray.length; i++) { - String text = strarray[i].trim(); - list.add(Long.valueOf(text)); - } - - long[] res = new long[list.size()]; - for (int i = 0; i < res.length; i++) { - res[i] = ((Long) list.get(i)).longValue(); - } - - return res; - } - - - /** - * 获取样式中字体的类型 - * - * @param g2d 图形上下文 - * @param style 样式 - * @param resolution 屏幕分辨率 - * @return 字体 - */ - public static Font getStyleFont(Graphics2D g2d, Style style, int resolution) { - FRFont font = style.getFRFont(); - Font rfont = initFontWithLocaleAndG2d(g2d, font, resolution); - if (!ComparatorUtils.equals(rfont, g2d.getFont())) { - g2d.setFont(rfont); - } - Color foreground = font.getForeground(); - if (!ComparatorUtils.equals(foreground, g2d.getPaint())) { - g2d.setPaint(foreground); - } - - return rfont; - } - - - private static Font initFontWithLocaleAndG2d(Graphics2D g2d, FRFont font, int resolution) { - Locale locale = GeneralContext.getLocale(); - Font rfont; - if (ComparatorUtils.equals(Locale.ENGLISH, locale)) { - rfont = FRFont.getInstance("Dialog", font.getStyle(), font.getSize()); - } - - rfont = font.applyResolutionNP(resolution); - //itext的bug 用SimSun导出无法实现粗体斜体, 其作者解释是使用basefont是不支持这些style的, 要转成itext的亚洲字体 - //这边不用instance of的原因就是不想把itext包引到applet包里面去. - if (g2d.toString().indexOf("PdfGraphics2D") != -1 && ComparatorUtils.equals(FRFont.DEFAULT_FONTNAME, font.getName())) { - //不要把这边的'宋体'改成'Simsun', 就这么设定的 - rfont = FRFont.getInstance(InterProviderFactory.getProvider().getLocText("Fine-Core_Base_Song_TypeFace"), rfont.getStyle(), rfont.getSize(), - font.getForeground(), font.getUnderline(), font.isStrikethrough(), font.isShadow(), - font.isSuperscript(), font.isSubscript()); - } - - return rfont; - } - - /** - * 获取样式中关于水平方向上的对齐类型 - * - * @param style 样式 - * @return 水平方向上的对齐类型 - */ - public static int getAlignment4Horizontal(Style style) { - return getAlignment4Horizontal(style, null); - } - - /** - * 获取DataMoodel中第columnIndex列的数据. - * - * @param model 取数的数据来源 - * @param columnIndex 取数的数据列序号 - * @return 返回数据数组Object[] - */ - public static Object[] getDistinctValues(DataModel model, int columnIndex) throws TableDataException { - ListSet list = new ListSet(); - if (columnIndex != DataModel.COLUMN_NAME_NOT_FOUND) { - for (int i = 0, len = model.getRowCount(); i < len; i++) { - list.add(model.getValueAt(i, columnIndex)); - } - } - - return list.toArray(); - } - - /** - * 获取水平方向上的对齐样式 - * - * @param style 样式 - * @param value 单元格的值,默认情况下,当不设置对齐类型时,如果单元格的值是数字则靠右对齐,字符串则靠左对齐 - * @return 水平方向上的对齐样式 - */ - public static int getAlignment4Horizontal(Style style, Object value) { - int horizontalAlignment = style.getHorizontalAlignment(); - //若是默认值:判断 bug5188 数字居右 - if (value != null && horizontalAlignment == Constants.NULL) { - if (value instanceof String) { - if (style.getFormat() instanceof NumberFormat || StableUtils.isNumber((String) value)) { - horizontalAlignment = Constants.RIGHT; - } else { - //字符串:靠左 - horizontalAlignment = Constants.LEFT; - } - } else if (value instanceof Number) { - horizontalAlignment = Constants.RIGHT; - } - } - return horizontalAlignment; - } - - /** - * 基本的画文本的方法,只考虑样式中的字体和对齐方式 - * - * @param g2d 图形上下文 - * @param width 画文本的区域的宽度 - * @param height 画文本的区域的高度 - * @param text 要画的文本 - * @param style 样式 - * @param resolution 屏幕分辨率 - */ - public static void drawStringStyleInRotation(Graphics2D g2d, int width, int height, String text, Style style, int resolution) { - if (StringUtils.isBlank(text)) { - return; - } - - Paint oldPaint = g2d.getPaint(); - Font oldFont = g2d.getFont(); - - if (style == null) { - style = Style.DEFAULT_STYLE; - } - - Font font = getStyleFont(g2d, style, resolution); - font = readExtraFont(g2d, font); - int horizontalAlignment = BaseUtils.getAlignment4Horizontal(style, text); - - if (style.getRotation() != 0 && style.getVerticalText() == Style.HORIZONTALTEXT) { - drawHorizontalText(g2d, text, font, style, width, height, horizontalAlignment); - } else { - drawRotationText(g2d, text, style, font, width, height, horizontalAlignment, resolution); - } - - g2d.setFont(oldFont); - g2d.setPaint(oldPaint); - } - - private static Font readExtraFont(Graphics2D g2d, Font font) { - ExtraClassManagerProvider pluginProvider = PluginModule.getAgent(PluginModule.ExtraCore); - if (pluginProvider != null) { - FontProcessor processor = pluginProvider.getSingle(FontProcessor.MARK_STRING); - if (processor != null) { - font = processor.readExtraFont(font); - g2d.setFont(font); - } - } - return font; - } - - private static void drawHorizontalText(Graphics2D g2d, String text, Font rfont, Style style, double width, double height, int horizontalAlignment) { - AffineTransform trans = new AffineTransform(); - trans.rotate(-Math.toRadians(style.getRotation())); - - double textX = width / 2.0; - double textY = height / 2.0; - - Dimension2D textDimension = GraphHelper.stringDimensionWithRotation(text, rfont, -style.getRotation(), g2d.getFontRenderContext()); - - if (textDimension.getWidth() < width) { - if (horizontalAlignment == Constants.LEFT) { - textX = textDimension.getWidth() / 2.0; - } else if (horizontalAlignment == Constants.RIGHT) { - textX = width - textDimension.getWidth() / 2.0 - style.getPaddingLeft() * - Math.cos(Math.toRadians(style.getRotation())); - } else { - } - } - - // adjust y, height. - if (textDimension.getHeight() < height) { - if (style.getVerticalAlignment() == Constants.TOP) { - textY = textDimension.getHeight() / 2.0; - } else if (style.getVerticalAlignment() == Constants.BOTTOM) { - textY = height - textDimension.getHeight() / 2.0 - style.getPaddingLeft() * Math.sin(Math.toRadians(style.getRotation())); - } else { - } - } - - GraphHelper.drawRotatedString(g2d, text, textX, textY, -style.getRotation()); - } - - private static void drawRotationText(Graphics2D g2d, String text, Style style, Font rfont, int width, int height, int horizontalAlignment, int resolution) { - AutoChangeLineAndDrawProcess process = AutoChangeLineAndDrawManager.getProcess(); - if (process != null) { - process.drawRotationText(g2d, text, new ObjectHolder(style), rfont, width, height, horizontalAlignment, resolution); - return; - } - - FontMetrics cellFM = GraphHelper.getFontMetrics(rfont); - List lineTextList = BaseUtils.getLineTextList(text, style, rfont, height, width, resolution); - - if (width <= 0 || lineTextList.isEmpty()) { - return; - } - - int textAscent = cellFM.getAscent(); - int textHeight = cellFM.getHeight(); - - int textY = calculateTextY(style, height, textHeight, textAscent, lineTextList, resolution); - - int maxWidth = 0; - for (int i = 0; i < lineTextList.size(); i++) { - String paint_str = (String) lineTextList.get(i); - int textWidth = cellFM.stringWidth(paint_str); - if (textWidth > maxWidth) { - maxWidth = textWidth; - } - } - for (int i = 0; i < lineTextList.size(); i++) { - String paint_str = (String) lineTextList.get(i); - //把自定义角度为0的横排和竖排区分开来 - if (style.getRotation() == 0 && style.getVerticalText() == style.HORIZONTALTEXT) { - maxWidth = cellFM.stringWidth(paint_str); - } - boolean textLonger = false;//KevinWang: 标志一下:是否串长大于列宽 - if (maxWidth > width - style.getPaddingLeft() - style.getPaddingRight()) { - textLonger = true;//added by KevinWang <处理分散对齐时使用> - } //待会串长大于列宽时需要特别处理:只从中抽取合适长度的串值显示 - - int textX = (int) calculateTextX(style, width, maxWidth, horizontalAlignment, resolution); - int textWidth = width - style.getPaddingRight(); - if (isAutomaticLine(style, horizontalAlignment, textLonger)) {//自动换行时 - GraphHelper.drawString2(g2d, paint_str, textX, textY, textWidth); - } else if (isDistributeAlign(style, horizontalAlignment, textLonger)) { - drawTextWihenDistributeAlign(g2d, paint_str, cellFM, textWidth, textX, textY); - } else { //这里不能删除 - GraphHelper.drawString(g2d, paint_str, textX, textY); - } - textY += textHeight;// TODO 只增加了Y. - textY += PX.toPixWithResolution(style.getLineSpacing(), resolution); - } - } - - public static int calculateTextY(Style style, int height, int textHeight, int textAscent, List lineTextList, int resolution) { - return calculateTextY(style, height, textHeight, textAscent, lineTextList, resolution, 1); - } - - /** - * 计算Y的高度 - * - * @param style 样式 - * @param height 总高度 - * @param textHeight 文本高度 - * @param textAscent 字体的基线到大多数字母数字字符顶部的距离 - * @param lineTextList 文本列 - * @param resolution 分辨率 - * @return Y高度 - */ - public static int calculateTextY(Style style, int height, int textHeight, int textAscent, List lineTextList, int resolution, int scale) { - // 计算Y的高度. - int textY = 0; - int textAllHeight = textHeight * lineTextList.size(); - double spacingBefore = PX.toPixWithResolution(style.getSpacingBefore() * scale, resolution); - double spacingAfter = PX.toPixWithResolution(style.getSpacingAfter() * scale, resolution); - double lineSpacing = PX.toPixWithResolution(style.getLineSpacing() * scale, resolution); - textAllHeight += spacingBefore + spacingAfter + lineSpacing * lineTextList.size(); - if (style.getVerticalAlignment() == Constants.TOP) { - } else if (style.getVerticalAlignment() == Constants.CENTER) { - if (height > textAllHeight) {// 如果所有文本的高度小于当前可以绘区域的高度,就从0开始画字符. - textY = (height - textAllHeight) / 2; - } - } else if (style.getVerticalAlignment() == Constants.BOTTOM) { - if (height > textAllHeight) { - textY = height - textAllHeight; - } - } - textY += textAscent;// 在绘画的时候,必须添加Ascent的高度. - textY += spacingBefore + lineSpacing;//james:加上"段前间距"+“行间距” - return textY; - } - - - public static int calculateTextX(Style style, Font rfont, String paint_str, int width, int textWidth, int horizontalAlignment) { - return calculateTextX(style, rfont, paint_str, width, textWidth, horizontalAlignment, 1); - } - - /** - * 计算X宽度 - * - * @param style 样式 - * @param rfont 字体 - * @param paint_str 字符串 - * @param width 宽度 - * @param textWidth 文本宽度 - * @param horizontalAlignment 垂向对齐 - * @return X宽度 - */ - public static int calculateTextX(Style style, Font rfont, String paint_str, int width, int textWidth, int horizontalAlignment, int scale) { - int textX = style.getPaddingLeft() * scale; - if (horizontalAlignment == Constants.CENTER) { - textX += (width - textWidth - textX) / 2; - } else if (horizontalAlignment == Constants.RIGHT) { - textX = width - style.getPaddingRight() * scale - textWidth; -//// // TODO alex:just for flash print && for font.Tahoma -// if (Boolean.TRUE == FRCoreContext.TMAP.get() -// && ComparatorUtils.equals(rfont.getFontName(), "Tahoma")) { -// textX -= paint_str.length() / 3; -// } - } - return textX; - } - - /** - * 计算X宽度 - * - * @param style 样式 - * @param width 宽度 - * @param textWidth 文本宽度 - * @param horizontalAlignment 垂向对齐 - * @param resolution 分辨率 - * @return X宽度 - */ - public static double calculateTextX(Style style, int width, int textWidth, int horizontalAlignment, int resolution) { - return calculateTextX(style, width, textWidth, horizontalAlignment, resolution, 1); - } - - /** - * 计算文本X位置 - * - * @param style 样式 - * @param width 宽度 - * @param textWidth 文本宽度 - * @param horizontalAlignment 水平对齐 - * @return X宽度 - */ - public static double calculateTextX(Style style, int width, int textWidth, int horizontalAlignment, int resolution, int scale) { - double textX = padding2PixExcludeRight(style.getPaddingLeft(), resolution); - if (horizontalAlignment == Constants.CENTER) { - textX += (width - textWidth - textX) / 2f; - } else if (horizontalAlignment == Constants.RIGHT) { - textX = width - style.getPaddingRight() * scale - textWidth; - } - return textX; - } - - /** - * 将缩减、段间距转为对应dpi下的pix Ps:除了右缩进 - * - * @param padding - * @param resolution - * @return - */ - public static double padding2PixExcludeRight(int padding, int resolution) { - return PX.toPixWithResolution(padding, resolution); - } - - /** - * 将右缩进转为对应dpi下的pix - * - * @param paddingRight - * @param resolution - * @return - */ - public static double paddingRight2Pix(int paddingRight, int resolution) { - if (paddingRight == Style.DEFAULT_PADDING) { - return 0; - } - return paddingRight; - } - - public static boolean isAutomaticLine(Style style, int horizontalAlignment, boolean textLonger) { - return horizontalAlignment == Constants.DISTRIBUTED - && style.getTextStyle() == Style.TEXTSTYLE_WRAPTEXT - || horizontalAlignment == Constants.DISTRIBUTED - && style.getTextStyle() == Style.TEXTSTYLE_SINGLELINE - && !textLonger; - } - - public static boolean isDistributeAlign(Style style, int horizontalAlignment, boolean textLonger) { - return horizontalAlignment == Constants.DISTRIBUTED - && style.getTextStyle() == Style.TEXTSTYLE_SINGLELINE - && textLonger; - } - - public static void drawTextWihenDistributeAlign(Graphics2D g2d, String paint_str, FontMetrics cellFM, int width, int textX, int textY) { - drawTextWihenDistributeAlign(g2d, paint_str, cellFM, width, textX, textY, 1f); - } - - /** - * 画字符串:分散对齐 - * @param scale 缩放比例,主目前要用于删除线、下划线及阴影的绘制 - */ - public static void drawTextWihenDistributeAlign(Graphics2D g2d, String paint_str, FontMetrics cellFM, int width, int textX, int textY, float scale) { - String lineText = getSingleLineText(paint_str, cellFM, width); - if (StringUtils.isNotEmpty(lineText)) { - GraphDrawHelper.drawString4DistributeAlign(g2d, lineText, textX, textY, width, scale); - } - } - - /** - * 获取用于单行显示的text - * - * @param lineText 分行显示时第i行的内容,但是也可能单行 - * @param cellFM 字体 - * @param width 宽度 - * @return 拆分后的字符串 - */ - private static String getSingleLineText(String lineText, FontMetrics cellFM, int width) { - // 单行显示时的分散对齐实现e - // 串长大于列宽时需要特别处理:只从中抽取合适长度的串值显示 - StringBuffer strBuff = new StringBuffer(); - for (int charIndex = 0; charIndex < lineText.length(); charIndex++) { - strBuff.append(lineText.charAt(charIndex)); - int buffWidth = cellFM.stringWidth(new String(strBuff)); - if (buffWidth > width) { //长度足够了,开始显示 - return strBuff.substring(0, 0 == charIndex ? 0 : charIndex - 1);//只画一行 - } - } - //上面的width没有减去padding-left,可能啥也没画 - return strBuff.toString(); - } - - /** - * 将输入字符串转换为实际字符,\代表转义字符。 - * - * @param text 字符串 - * @return the real value 实际字符 - */ - public static String textToString(String text) { - //跟这里的drawText算法是一致的,这样"所见即所得", - //如果把drawText的参数text先用此方法转换也行的,但是会遍历俩次,所以先留着 - if (text == null) { - return ""; - } - - int len = text.length(); - StringBuffer sb = new StringBuffer(len); - - for (int i = 0; i < len; i++) { - char c = text.charAt(i); - if (c == '\\' && i + 1 < len) { - char next = text.charAt(i + 1); - if (next == 'n') { - i++; - c = '\n'; - } else if (next == '\\') { - i++; - } - - } - sb.append(c); - } - return sb.toString(); - } - - /** - * daniel: 自动换行算法, 这个算法要求跟DHTML中Table的自动换行表现结果一样 - * 所以统一72dpi进行处理 - * - * @param text - * @param style - * @param paintWidth - * @return - */ - public static List getLineTextList(String text, Style style, Font font, double paintWidth, int resolution) { - List lineTextList = new ArrayList(); - if (text == null || text.length() <= 0) { - return lineTextList; - } - - style = style == null ? Style.DEFAULT_STYLE : style; - - if (style.getRotation() != 0) { - lineTextList.add(text); - return lineTextList; - } - - if (style.getTextStyle() != Style.TEXTSTYLE_WRAPTEXT) { - return lineTextListNotChangeLine(lineTextList, text); - } - // 自动换行 - else { - UNIT width = FU.valueOfPix((int) paintWidth, resolution); - return lineTextListAutoChangeLine(lineTextList, text, font, style, width, resolution); - } - } - - private static List lineTextListNotChangeLine(List lineTextList, String text) { - char tmpChar; - StringBuffer tmpTextBuf = new StringBuffer(); - for (int t = 0; t < text.length(); t++) { - tmpChar = text.charAt(t); - if (tmpChar == '\\') {// 判断是否是 "\n" - if (t + 1 < text.length() && text.charAt(t + 1) == 'n') { - // 是"\n"字符串,但不是换行符. - t++; - lineTextList.add(tmpTextBuf.toString()); - tmpTextBuf.delete(0, tmpTextBuf.length()); - } else { - tmpTextBuf.append(tmpChar); - } - } else { - tmpTextBuf.append(tmpChar); - } - } - - // 最后一个 - if (tmpTextBuf.length() > 0) { - lineTextList.add(tmpTextBuf.toString()); - tmpTextBuf.delete(0, tmpTextBuf.length()); - } - - return lineTextList; - } - - /** - * 这里需要用resolution 72的dpi进行分行,因为96dpi会导致font有小数导致获取的宽度不正确 - * - * @param lineTextList - * @param text - * @param style - * @return - */ - private static List lineTextListAutoChangeLine(List lineTextList, String text, Font font, Style style, UNIT unitWidth, int resolution) { - - AutoChangeLineAndDrawProcess process = AutoChangeLineAndDrawManager.getProcess(); - if (process != null) { - return process.autoChangeLine(text, new ObjectHolder(style), unitWidth); - } - if (font == null) { - font = style.getFRFont(); - } - FontMetrics fontMetrics = GraphHelper.getFontMetrics(font); - double paintWidth = unitWidth.toPixD(resolution); - double width = paintWidth - style.getPaddingLeft() - style.getPaddingRight() - style.getBorderLeftWidth(); - StringBuffer lineTextBuf = new StringBuffer(); - int lineTextWidth = 0; - - StringBuffer wordBuf = new StringBuffer(); - int wordWidth = 0; - int[] tmpWidth = new int[2]; - tmpWidth[0] = wordWidth; - tmpWidth[1] = lineTextWidth; - - lineTextListDealWithText(text, lineTextList, width, tmpWidth, wordBuf, lineTextBuf, fontMetrics); - - // 最后处理 - if (tmpWidth[1] + tmpWidth[0] > width && lineTextBuf.length() > 0) { - lineTextList.add(lineTextBuf.toString()); - lineTextList.add(wordBuf.toString()); - } else { - lineTextBuf.append(wordBuf); - lineTextList.add(lineTextBuf.toString()); - } - return lineTextList; - } - private static void lineTextListDealWithText(String text, List lineTextList, double width, int[] tmpWidth, - StringBuffer wordBuf, StringBuffer lineTextBuf, FontMetrics fontMetrics) { - for (int t = 0; t < text.length(); t++) { - if (t != 0 && isNumOrLetter(text.charAt(t)) && isNumOrLetter(text.charAt(t - 1))) { - dealWithTextNumOrLetter(text, t, lineTextList, width, tmpWidth, wordBuf, lineTextBuf, fontMetrics); - } else if (text.charAt(t) == '\n' || (text.charAt(t) == '\r' && t + 1 < text.length() - 1 && text.charAt(t + 1) != '\n')) { - dealWithTextChangeLineSymbol(text, t, lineTextList, width, tmpWidth, wordBuf, lineTextBuf, fontMetrics); - } else if (text.charAt(t) == '\\' && t + 1 < text.length() && text.charAt(t + 1) == 'n') {// 判断是否是 "\n" - // 是"\n"字符串,但不是换行符,依然需要换行. - dealWidthTextManualChangeLine(text, t, lineTextList, width, tmpWidth, wordBuf, lineTextBuf, fontMetrics); - // 需要跳过后面的n - t++; - } else { - int increaseStep = 0; - if (text.charAt(t) == '\\' && t + 1 < text.length() && text.charAt(t + 1) == '\\') {// 判断是否是转义字符'\' - // _denny: 增加了转义字符'\\'用来表示\,使"\n"可以输入 - t++; - increaseStep++; - } - if (tmpWidth[1] + tmpWidth[0] > width && lineTextBuf.length() > 0) { - if (isPunctuationAtLineHead(t, text)) { - for (int index = lineTextBuf.length(); index > 0; index--) { - char prec = lineTextBuf.charAt(index - 1); - lineTextBuf.deleteCharAt(index - 1); - if (!isPunctuation(prec)) { - break; - } - } - } - lineTextList.add(lineTextBuf.toString()); - lineTextBuf.delete(0, lineTextBuf.length()); - tmpWidth[1] = isPunctuationAtLineHead(t, text) ? dealWithPunctuationAtLinehead(t, fontMetrics, text, lineTextBuf, wordBuf.length(), increaseStep) : 0; - } - lineTextBuf.append(wordBuf); - tmpWidth[1] += tmpWidth[0]; - - wordBuf.delete(0, wordBuf.length()); - tmpWidth[0] = 0; - wordBuf.append(text.charAt(t)); - tmpWidth[0] = fontMetrics.charWidth(text.charAt(t)); - } - } - } - - - - /** - * 标点符号是否在换行后的行首 - */ - private static boolean isPunctuationAtLineHead(int t, String text) { - return t > 1 && BaseUtils.isPunctuation(text.charAt(t - 1)); - } - - private static int dealWithPunctuationAtLinehead(int t, FontMetrics fontMetrics, String text, StringBuffer lineTextBuf, int wordBufLength, int increaseStep) { - //lineTextBuf 最后一个字符下标 与 text当前字符下标 t 的距离 + 1 - int indexDistance = 1 + wordBufLength + increaseStep; - if (t < indexDistance) { - return 0; - } - int lineWidth = 0; - for (int index = t - indexDistance; index >= 0; index--) { - lineWidth += fontMetrics.charWidth(text.charAt(index)); - lineTextBuf.insert(0, text.charAt(index)); - if (!isPunctuation(text.charAt(index))) { - break; - } - } - return lineWidth; - } - - private static void dealWithTextNumOrLetter(String text, int t, List lineTextList, double width, int[] tmpWidth, - StringBuffer wordBuf, StringBuffer lineTextBuf, FontMetrics fontMetrics) { - if (tmpWidth[0] + fontMetrics.charWidth(text.charAt(t)) > width) { - if (tmpWidth[1] > 0) { - lineTextList.add(lineTextBuf.toString()); - lineTextBuf.delete(0, lineTextBuf.length()); - tmpWidth[1] = 0; - } - - lineTextList.add(wordBuf.toString()); - wordBuf.delete(0, wordBuf.length()); - tmpWidth[0] = 0; - } - - wordBuf.append(text.charAt(t)); - tmpWidth[0] += fontMetrics.charWidth(text.charAt(t)); - } - - private static void dealWithTextChangeLineSymbol(String text, int t, List lineTextList, double width, int[] tmpWidth, - StringBuffer wordBuf, StringBuffer lineTextBuf, FontMetrics fontMetrics) { - wordBuf.append('\n'); - if (tmpWidth[1] + tmpWidth[0] > width && lineTextBuf.length() > 0) { - lineTextList.add(lineTextBuf.toString()); - lineTextList.add(wordBuf.toString()); - } else { - lineTextBuf.append(wordBuf); - lineTextList.add(lineTextBuf.toString()); - } - lineTextBuf.delete(0, lineTextBuf.length()); - tmpWidth[1] = 0; - wordBuf.delete(0, wordBuf.length()); - tmpWidth[0] = 0; - } - - private static void dealWidthTextManualChangeLine(String text, int t, List lineTextList, double width, int[] tmpWidth, - StringBuffer wordBuf, StringBuffer lineTextBuf, FontMetrics fontMetrics) { - t++;// 忽略'n'字符. - wordBuf.append('\n'); - if (tmpWidth[1] + tmpWidth[0] > width && lineTextBuf.length() > 0) { - lineTextList.add(lineTextBuf.toString()); - lineTextList.add(wordBuf.toString()); - } else { - lineTextBuf.append(wordBuf); - lineTextList.add(lineTextBuf.toString()); - } - lineTextBuf.delete(0, lineTextBuf.length()); - tmpWidth[1] = 0; - wordBuf.delete(0, wordBuf.length()); - tmpWidth[0] = 0; - } - - - /** - * @param cuChar - * @return - * @see StableUtils - * @deprecated - */ - public static boolean isNum(char cuChar) { - return StableUtils.isNum(cuChar); - } - - - /** - * 判断字符是否为数字或字母 - * - * @param curChar 被检查的字符 - * @return 是否为数字或字母 - */ - public static boolean isNumOrLetter(char curChar) { - return GeneralUtils.isLetter(curChar) || StableUtils.isNum(curChar); - } - - public static boolean isPunctuation(char c) { - int type = Character.getType(c); - return type == Character.OTHER_PUNCTUATION - || type == Character.DASH_PUNCTUATION - || type == Character.START_PUNCTUATION - || type == Character.END_PUNCTUATION - || type == Character.CONNECTOR_PUNCTUATION; - } - - - public static List getLineTextList(String text, Style style, Font font, double paintHeight, double paintWidth) { - return getLineTextList(text, style, font, paintHeight, paintWidth, Constants.DEFAULT_PRINT_AND_EXPORT_RESOLUTION); - } - - /** - * james daniel 放一起 - * 同时含有height和width参数表示会根据style自动判断字体为竖排还是横排 - * TODO - */ - public static List getLineTextList(String text, Style style, Font font, double paintHeight, double paintWidth, int resolution) { - //正常文字 - if (style == null - || style.getVerticalText() != Style.VERTICALTEXT) {//james:正常的文字时 - return BaseUtils.getLineTextList(text, style, font, paintWidth, resolution); - } - ExtraClassManagerProvider pluginProvider = PluginModule.getAgent(PluginModule.ExtraCore); - if (pluginProvider != null) { - VerticalTextProcessor processor = pluginProvider.getSingle(VerticalTextProcessor.XML_TAG, DefaultVerticalTextProcessor.class); - String[] res = processor.process(text, style, font, paintHeight, paintWidth, resolution); - return Arrays.asList(res); - } - String[] res = new DefaultVerticalTextProcessor().process(text, style, font, paintHeight, paintWidth, resolution); - return Arrays.asList(res); - } - - /** - * 返回边框宽 - * - * @param borderType 边框类型 - * @return 宽度 - */ - public static int getBorderWidth(int borderType) { - switch (borderType) { - case Constants.LINE_NONE: - return 0; - case Constants.LINE_SLIM: - return 1; - case Constants.LINE_THIN: - return 1; - case Constants.LINE_DASH: - return 1; - case Constants.LINE_HAIR: - return 1; - case Constants.LINE_HAIR2: - return 1; - case Constants.LINE_THICK: - return 3; - case Constants.LINE_DOT: - return 1; - default: - return 2; - } - } - - /** - * 将边框转为对应的字符串描述 - * - * @param borderStyle 边框线型 - * @return web端对应的边框 - */ - public static String border2Style(int borderStyle) { - switch (borderStyle) { - case Constants.LINE_NONE: - return "none"; - case Constants.LINE_SLIM: - return "solid"; - case Constants.LINE_THIN: - return "solid"; - case Constants.LINE_MEDIUM: - return "solid"; - case Constants.LINE_THICK: - return "solid"; - case Constants.LINE_DOUBLE: - return "double"; - case Constants.LINE_DOT: - return "double"; - case Constants.LINE_DASH_DOT: - return "double"; - case Constants.LINE_DASH_DOT_DOT: - return "dotted"; - default: - return "dashed"; - } - } - - /** - * 克隆对象 - * - * @param object 对象 - * @return 克隆出的对象 - * @throws CloneNotSupportedException 不被支持的克隆异常 - * @see StableUtils#cloneObject(Object) - * @deprecated - */ - public static Object cloneObject(Object object) throws CloneNotSupportedException { - return StableUtils.cloneObject(object); - } - - - /** - * 把java.util.Map转成一段JSONObject的String与上面方法对应 - * - * @param map map对象 - * @return json对象 - * @throws JSONException json异常 - */ - public static JSONObject map2JSON(Map map) throws JSONException { - JSONObject jo = new JSONObject(); - Iterator iter = map.keySet().iterator(); - while (iter.hasNext()) { - Map.Entry entry = (Map.Entry) iter.next(); - Object value = entry.getValue(); - if (value instanceof FArray) { - JSONArray ja = new JSONArray(); - FArray array = (FArray) value; - for (int i = 0; i < array.length(); i++) { - ja.put(array.elementAt(i)); - } - value = ja; - } - jo.put((String) entry.getKey(), value); - } - return jo; - } - - /** - * 将一个对象转化成json样式的字符串 - * - * @param o 待转化的对象 - * @return json样式的字符串 - * @throws JSONException json异常 - * @see EmbedJson#encode(Object) (Object) - * @deprecated - */ - public static String jsonEncode(Object o) throws JSONException { - return EmbedJson.encode(o); - } - - - /** - * 将一个字符串转化成JSON格式的对象 - * - * @param str 要转化的字符串 - * @return JSON格式的对象 - * @throws JSONException json异常 - * @see JSONUtils#jsonDecode(String) - * @deprecated - */ - public static Object jsonDecode(String str) throws JSONException { - return JSONUtils.jsonDecode(str); - } - - /** - * 检查图片1和2是否相同. - * - * @param img1 图片1 - * @param img2 图片2 - * @return 图片1和2是否相同 - */ - public static boolean imageEquals(Image img1, Image img2) { - if (img1 == img2) { - return true; - } - - if (img1 == null || img2 == null) {//null < not null - return img1 == null && img2 == null; - } - - //开始比较图片. - byte[] buf1 = GeneralXMLTools.imageEncode(img1); - byte[] buf2 = GeneralXMLTools.imageEncode(img2); - if (buf1.length != buf2.length) { - return false; - } - - for (int i = 0; i < buf1.length; i++) { - if (buf1[i] != buf2[i]) { - return false; - } - } - - return true; - } - - /** - * 根据数据集名获取数据模型 - * - * @param cal 算子 - * @param tdName 列表名 - * @return 数据模型 - */ - public static DataModel getDataModelFromTableDataName(Calculator cal, String tdName) { - String tableDataName = tdName; - //先看当前的报表中的私有数据源 - DataModel resultSet = SynchronizedLiveDataModelUtils.getSELiveDataModel4Share(cal, tableDataName); - if (resultSet == null) { - TableData td = TableDataAssist.getTableData(cal, tableDataName); - resultSet = td == null ? null : td.createDataModel(cal); - } - return resultSet; - } - - - /** - * kunsnat: List转化为二维表 - * - * @param list 列表 - * @return 二维数组 - */ - public static Object[][] list2Array2D(List list) { - int rowNum = list.size(); - int colNum = 0; - for (int i = 0; i < rowNum; i++) { - List row = (List) list.get(i); - if (row.size() > colNum) { - colNum = row.size(); - } - } - Object[][] result = new Object[rowNum][colNum]; - - for (int i = 0; i < rowNum; i++) { - List row = (List) list.get(i); - for (int j = 0; j < colNum; j++) { - if (j < row.size()) { - result[i][j] = row.get(j); - } else { - result[i][j] = null; - } - } - } - - return result; - } - - /** - * 判断当前Env下是否有lic文件 - * - * @return 判断当前Env下是否有lic文件 - */ - public static boolean checkLicExist() { - - if (ServerPreferenceConfig.getInstance().isLicUseLock()) { - return true;//加密狗 - } else if (!LicenseConfigManager.getInstance().isUseFile()) { - //不使用文件,说明用户配置了注册信息,一定是注册了 - return true; - } - - try { - String licName = FRContext.getCommonOperator().getLicenseName(); - byte[] bytes = WorkContext.getWorkResource().readFully(StableUtils.pathJoin(ProjectConstants.RESOURCES_NAME, licName)); - return bytes != null && bytes.length != 0; - } catch (Exception ignored) { - } - - return false; - } - - /** - * 判断是否内容为图表相关. - * - * @param cellOption 单元格属性 - * @return 返回是否为图表单元格相关. - */ - public static boolean isChartCell(JSONObject cellOption) { - if (cellOption != null) { - JSONObject value = cellOption.optJSONObject("value"); - if (value != null) { - return ComparatorUtils.equals("simplechart", value.optString("type")); - } - } - - return false; - } -} diff --git a/designer-form/src/main/java/com/fr/design/fit/common/NewFormStyle.java b/designer-form/src/main/java/com/fr/design/fit/common/NewFormStyle.java deleted file mode 100644 index a937ba2d4..000000000 --- a/designer-form/src/main/java/com/fr/design/fit/common/NewFormStyle.java +++ /dev/null @@ -1,2030 +0,0 @@ -/* - * Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved. - */ -package com.fr.design.fit.common; - -import com.fr.base.BaseFormula; -import com.fr.base.CoreDecimalFormat; -import com.fr.base.FRContext; -import com.fr.base.FormatRepository; -import com.fr.base.GraphHelper; -import com.fr.base.ImageProvider; -import com.fr.base.Painter; -import com.fr.base.Style; -import com.fr.base.Utils; -import com.fr.base.background.ImageBackground; -import com.fr.common.annotations.Open; -import com.fr.data.DataBaseUtils; -import com.fr.general.Background; -import com.fr.general.ComparatorUtils; -import com.fr.general.DateUtils; -import com.fr.general.DefaultValues; -import com.fr.general.FRFont; -import com.fr.general.GeneralUtils; -import com.fr.json.JSONException; -import com.fr.json.JSONObject; -import com.fr.stable.AssistUtils; -import com.fr.stable.Constants; -import com.fr.stable.CoreGraphHelper; -import com.fr.stable.StableUtils; -import com.fr.stable.StringUtils; -import com.fr.stable.unit.PT; -import com.fr.stable.web.Repository; -import com.fr.stable.web.ServletContext; -import com.fr.stable.web.ServletContextAdapter; -import org.jetbrains.annotations.Nullable; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.Paint; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.geom.Rectangle2D; -import java.io.InvalidObjectException; -import java.io.Serializable; -import java.sql.Clob; -import java.text.DateFormat; -import java.text.Format; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * 用于表示样式的类,包括边框、颜色、字体、缩进、间距等 - * 注意:这是一个开放类,所有的修改都要注意保持兼容 - */ -@Open -public class NewFormStyle extends Style implements Serializable, Cloneable { - - // temp rectangle - private static Rectangle2D tempRectangle2D = new Rectangle2D.Double(0, 0, 0, 0); - - public static final int TEXTSTYLE_WRAPTEXT = 0; // 换行. - public static final int TEXTSTYLE_SINGLELINE = 1; // 单行,超出部分不显示. - public static final int TEXTSTYLE_SINGLELINEADJUSTFONT = 2; // 单行,调整字体来显示所有的字. - public static final int TEXTSTYLE_MULTILINEADJUSTFONT = 3; //多行,固定单元格高和宽,调整字体来显示所有的字 - - public static final int VERTICALTEXT = 1;// 竖排,与Excel中的设置值相同 - public static final int HORIZONTALTEXT = 0;// 横排 - - public static final int LEFT_TO_RIGHT = 1;// JAMES:垂直文字时,文字为从左向右顺序排列 - public static final int RIGHT_TO_LEFT = 0;// JAMES:垂直文字时,文字为从右向左顺序排列 - - //EXCEL 宋体11号字, 一个缩进单位对应96dpi下27px - public static final int PADDING_ARG = 27; - public static final int DEFAULT_PADDING = 2; - /** - * 细线透明度值 - */ - public static final double FACTORY_ALPHA = 0.4; - public static final NewFormStyle NULL_STYLE = null; - - /** - * Default Style - */ - public static final NewFormStyle DEFAULT_STYLE = new NewFormStyle(); - - /** - * Border Style - */ - public static final NewFormStyle BORDER_STYLE = new NewFormStyle(); - - private static final long serialVersionUID = -1675056857456167839L; - private static final int MAX_FONT_SIZE = 100; - private static final int N_SIZE = 9; - private static final int MIN_SIZE = 8; - private static final int MAX_SIZE = 26; - - private static final int LINE_HEIGHT_FIX = 4; - private static final int LINE_HEIGHT_FIX2 = 3; - - private static class ContentLineGroup { - Style style; - List newLineTextList; - int newTextHeight; - - public ContentLineGroup(Style style, List lineList, int textHeight) { - this.style = style; - this.newLineTextList = lineList; - this.newTextHeight = textHeight; - } - - public int totalHeight() { - return newTextHeight * newLineTextList.size(); - } - } - - private static Map clsFontFamily = null; - - // 全局Style的map - private static Map initializeStyle = new ConcurrentHashMap();// - - static { - ServletContext.addServletContextListener(new ServletContextAdapter() { - @Override - public void onServletStop() { - initializeStyle.clear(); - } - }); - } - - // format - private Format format = null; - - // element font. - private FRFont frFont = null; - - private Background background = null; - - // border. - private byte border_top = Constants.LINE_NONE; - private byte border_left = Constants.LINE_NONE; - private byte border_bottom = Constants.LINE_NONE; - private byte border_right = Constants.LINE_NONE; - private Color border_top_color = Color.BLACK; - private Color border_left_color = Color.BLACK; - private Color border_bottom_color = Color.BLACK; - private Color border_right_color = Color.BLACK; - - // alignment. - private int horizontal_alignment = Constants.NULL; - private int vertical_alignment = Constants.CENTER; - - // TextStyle - private int textStyle = NewFormStyle.TEXTSTYLE_WRAPTEXT; - - // james: verticalText - private int verticalText = NewFormStyle.HORIZONTALTEXT;// 默认为0,水平方向 - - // james: the direction of text when the text is vertical - private int textDirection = NewFormStyle.RIGHT_TO_LEFT;// 默认为从右向左的顺序 - - private int rotation = 0; - - private byte imageLayout = Constants.IMAGE_CENTER;//现在默认改为center了 - - //padding有两个计量单位, 一种是以前的pt, 一种是现在的, 为了兼容excel的 - //设计器中设置1个单位, 兼容为以前的27pt - // 左缩进 - private int paddingLeft = DEFAULT_PADDING; - // 右缩进 - private int paddingRight = DEFAULT_PADDING; - - // 段前间距 - private byte spacingBefore = 0; - // 段后间距 - private byte spacingAfter = 0; - // 行间距h - private byte lineSpacing = 0; - - private String contentClsCss = StringUtils.EMPTY; - private Map contentStyleCssMap = new HashMap(); - - private String borderClsCss = StringUtils.EMPTY; - private Map borderStyleCssMap = new HashMap(); - - /** - * Constructor. - */ - protected NewFormStyle() { - //peter:这里主动从Context, 获得默认的FRFont的值. - DefaultValues defaultValues = FRContext.getDefaultValues(); - this.frFont = defaultValues.getFRFont(); - - // HTML输出 CSS初始化 - this.contentClsCss = this.contentStyle2class(this.contentStyleCssMap); - this.borderClsCss = this.border2Class(this.borderStyleCssMap); - } - - private NewFormStyle(Background background, Format format, FRFont frFont, - int border_top, Color border_top_color, int border_bottom, Color border_bottom_color, - int border_left, Color border_left_color, int border_right, Color border_right_color, - int horizontal_alignment, int vertical_alignment, int textStyle, - int verticalText, int textDirection, int rotation, int imageLayout, - int paddingLeft, int paddingRight, int spacingBefore, int spacingAfter, int lineSpacing) { - this.background = background; - this.format = format; - this.frFont = frFont; - - this.border_top = (byte) border_top; - this.border_top_color = border_top_color; - this.border_bottom = (byte) border_bottom; - this.border_bottom_color = border_bottom_color; - this.border_left = (byte) border_left; - this.border_left_color = border_left_color; - this.border_right = (byte) border_right; - this.border_right_color = border_right_color; - - this.horizontal_alignment = (byte) horizontal_alignment; - this.vertical_alignment = (byte) vertical_alignment; - this.textStyle = (byte) textStyle; - - this.verticalText = (byte) verticalText; - this.textDirection = (byte) textDirection; - this.rotation = (short) rotation; - this.imageLayout = (byte) imageLayout; - - this.paddingLeft = paddingLeft; - this.paddingRight = paddingRight; - - this.spacingBefore = (byte) spacingBefore; - this.spacingAfter = (byte) spacingAfter; - this.lineSpacing = (byte) lineSpacing; - - // HTML输出 CSS初始化 - this.contentClsCss = this.contentStyle2class(this.contentStyleCssMap); - this.borderClsCss = this.border2Class(this.borderStyleCssMap); - } - - private static Map getclsFontFamily() { - if (clsFontFamily == null) { - clsFontFamily = new HashMap() { - { - put("Arial Black", "fnab"); - put("Basic Sans SF", "fnbs"); - put("Book Antiqua", "fnba"); - put("Calibri", "fnci"); - put("Comic Sans MS", "fncs"); - put("Courier New", "fncn"); - put("Elementary SF", "fnes"); - put("Garamond", "fngd"); - put("Georgia", "fnga"); - put("Letter Gothic", "fnlg"); - put("Lucida Console", "fnlc"); - put("Marigold", "fnmd"); - put("MS Sans Serif", "fnms"); - put("MS Gothic", "fnmg"); - put("MS PGothic", "fnmpg"); - put("MS Mincho", "fnmm"); - put("MS P Mincho", "fnmpm"); - put("MingLiU", "fnml"); - put("SimHei", "fnsh"); - put("System", "fnsm"); - put("Tahoma", "fnta"); - put("Times New Roman", "fntn"); - put("Trebuchet MS", "fntms"); - put("Verdana", "fnva"); - - put("SimSun", "fnss"); - put("Arial", "fnar"); - put("Microsoft YaHei", "fnyh"); - put("KaiTi", "fnkt"); - } - }; - } - - return clsFontFamily; - } - - /** - * 设置样式 - * - * @param format 格式g - * @return 样式y - */ - public NewFormStyle deriveFormat(Format format) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 获取实例 - */ - public static NewFormStyle getInstance(Format format) { - return DEFAULT_STYLE.deriveFormat(format); - } - - /** - * 设置字体 - * - * @param frFont 字体 - * @return 样式 - */ - public NewFormStyle deriveFRFont(FRFont frFont) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * getInstance - */ - public static NewFormStyle getInstance() { - NewFormStyle style = new NewFormStyle(); - - Object valueStyle = initializeStyle.get(style); - if (valueStyle != null) { - return (NewFormStyle) valueStyle; - } else { - initializeStyle.put(style, style); - return style; - } - } - - /** - * getInstance - */ - private static NewFormStyle getInstance(Background background, Format format, FRFont frFont, - int border_top, Color border_top_color, int border_bottom, Color border_bottom_color, - int border_left, Color border_left_color, int border_right, Color border_right_color, - int horizontal_alignment, int vertical_alignment, int textStyle, - int verticalText, int textDirection, int rotation, int imageLayout, - int paddingLeft, int paddingRight, int spacingBefore, int spacingAfter, int lineSpacing) { - NewFormStyle style = new NewFormStyle(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - - Object valueStyle = initializeStyle.get(style); - if (valueStyle != null) { - return (NewFormStyle) valueStyle; - } else { - initializeStyle.put(style, style); - return style; - } - } - - /** - * getInstance - */ - public static NewFormStyle getInstance(FRFont frFont) { - if (frFont == null) { - return NewFormStyle.getInstance(); - } - return DEFAULT_STYLE.deriveFRFont(frFont); - } - - /** - * 设置背景 - * - * @param background 背景 b - * @return 样式 y - */ - public NewFormStyle deriveBackground(Background background) { - if (background instanceof ImageBackground) { - return new NewFormStyle(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * getInstance - */ - public static NewFormStyle getInstance(Background background) { - return DEFAULT_STYLE.deriveBackground(background); - } - - /** - * 去掉边框和单元格背景 - * - * @return 样式y - */ - public NewFormStyle deriveBorderBackgroundNone() { - return getInstance(null, format, frFont, - Constants.LINE_NONE, border_top_color, Constants.LINE_NONE, border_bottom_color, - Constants.LINE_NONE, border_left_color, Constants.LINE_NONE, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置边框 - * - * @param border_top 上边框像素 - * @param border_top_color 上边框颜色s - * @param border_bottom 下 x - * @param border_bottom_color 下 x - * @param border_left 左 z - * @param border_left_color 左z - * @param border_right 右y - * @param border_right_color 右y - * @return 样式y - */ - public NewFormStyle deriveBorder(int border_top, Color border_top_color, - int border_bottom, Color border_bottom_color, - int border_left, Color border_left_color, - int border_right, Color border_right_color) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置上边框 - * - * @param border_top 上边框尺寸s - * @param border_top_color 上边框颜色 s - * @return 样式 y - */ - public NewFormStyle deriveBorderTop(int border_top, Color border_top_color) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置下边框 - * - * @param border_bottom 下边框尺寸 x - * @param border_bottom_color 下颜色x - * @return 样式y - */ - public NewFormStyle deriveBorderBottom(int border_bottom, Color border_bottom_color) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置左边框 - * - * @param border_left 尺寸 z - * @param border_left_color 颜色y - * @return 样式y - */ - public NewFormStyle deriveBorderLeft(int border_left, Color border_left_color) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置右边框 - * - * @param border_right 尺寸 c - * @param border_right_color 颜色 y - * @return 样式 y - */ - public NewFormStyle deriveBorderRight(int border_right, Color border_right_color) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置水平方向 - * - * @param horizontal_alignment 水平方向s - * @return 样式 y - */ - public NewFormStyle deriveHorizontalAlignment(int horizontal_alignment) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置垂直方向 - * - * @param vertical_alignment 垂直方向c - * @return 样式 - * @see Constants#TOP - * @see Constants#CENTER - * @see Constants#BOTTOM - */ - public NewFormStyle deriveVerticalAlignment(int vertical_alignment) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置单元格展示样式(自动换行, 单行显示, 多行显示等) - * - * @param textStyle 文字样式 - * @return 样式 - * @see NewFormStyle#TEXTSTYLE_WRAPTEXT - * @see NewFormStyle#TEXTSTYLE_SINGLELINE - * @see NewFormStyle#TEXTSTYLE_SINGLELINEADJUSTFONT - * @see NewFormStyle#TEXTSTYLE_MULTILINEADJUSTFONT - */ - public NewFormStyle deriveTextStyle(int textStyle) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置单元格方向 - * - * @param textDirection 文本方向w - * @return 样式t - */ - public NewFormStyle deriveTextDirection(int textDirection) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置单元格垂直方向 - * - * @param verticalText 垂直方向c - * @return 样式 - */ - public NewFormStyle deriveVerticalText(int verticalText) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置旋转方向 - * - * @param rotation 旋转方向 the new rotation of cell (between -90 and 90 degrees). - * @return 样式 - */ - public NewFormStyle deriveRotation(int rotation) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置图片布局 - * - * @param imageLayout the new image layout 图片布局t - * @return 样式 - * @see Constants#IMAGE_TILED - * @see Constants#IMAGE_CENTER - * @see Constants#IMAGE_EXTEND - */ - public NewFormStyle deriveImageLayout(int imageLayout) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置缩进 - * - * @param paddingLeft 左缩进 - * @param paddingRight 右缩进 - * @return 样式 - */ - public NewFormStyle derivePadding(int paddingLeft, int paddingRight) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置左缩进 - * - * @param paddingLeft 左缩进 - * @return 样式 - */ - public NewFormStyle derivePaddingLeft(int paddingLeft) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置右缩进 - * - * @param paddingRight 右缩进 - * @return 样式 - */ - public NewFormStyle derivePaddingRight(int paddingRight) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置段前间距 - * - * @param spacingBefore 段前间距d - * @return 样式 y - */ - public NewFormStyle deriveSpacingBefore(int spacingBefore) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置段后间距 - * - * @param spacingAfter 段后间距d - * @return 样式y - */ - public NewFormStyle deriveSpacingAfter(int spacingAfter) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 设置行间距 - * - * @param lineSpacing 行间距h - * @return 样式y - */ - public NewFormStyle deriveLineSpacing(int lineSpacing) { - return getInstance(background, format, frFont, - border_top, border_top_color, border_bottom, border_bottom_color, - border_left, border_left_color, border_right, border_right_color, - horizontal_alignment, vertical_alignment, textStyle, - verticalText, textDirection, rotation, imageLayout, - paddingLeft, paddingRight, spacingBefore, spacingAfter, lineSpacing); - } - - /** - * 对象转为json格式 - * - * @param repo 浏览器上下文 - * @param size 单元格大小 - * @return json格式数据 - */ - public JSONObject toJSONObject(Repository repo, Dimension size) throws JSONException { - JSONObject jo = new JSONObject(); - if (background != null) { - jo.put("background", background.toJSONObject(repo, size)); - } - // 不是默认值才输出,节省流量 - if (frFont != null && !ComparatorUtils.equals(frFont, FRContext.getDefaultValues().getFRFont())) { - jo.put("font", frFont.toJSONObject(repo)); - } - - if (!checkLeftRightTopBottom4b0()) { - jo.put("border", border2JSONObject()); - jo.put("borderCss", borderClsCss); - } - - createAlignAndTextStyleConfig(jo); - if (rotation != 0) { - jo.put("ro", rotation); - } - if (imageLayout != Constants.IMAGE_CENTER) { - jo.put("il", imageLayout); - } - createSpacingAndPaddingConfig(jo); - - return jo; - } - - private void createAlignAndTextStyleConfig(JSONObject jo) throws JSONException { - if (horizontal_alignment != Constants.NULL) { - jo.put("ha", horizontal_alignment); - } - if (vertical_alignment != Constants.CENTER) { - jo.put("va", vertical_alignment); - } - if (textStyle != TEXTSTYLE_WRAPTEXT) { - jo.put("ts", textStyle); - } - if (verticalText != NewFormStyle.HORIZONTALTEXT) { - jo.put("vt", verticalText); - } - if (textDirection != RIGHT_TO_LEFT) { - jo.put("td", textDirection); - } - jo.put("contentCss", contentClsCss); - } - - private void createSpacingAndPaddingConfig(JSONObject jo) throws JSONException { - if (paddingLeft != DEFAULT_PADDING) { - jo.put("pl", paddingLeft); - } - if (paddingRight != DEFAULT_PADDING) { - jo.put("pr", paddingRight); - } - if (spacingBefore != 0) { - jo.put("sb", spacingBefore); - } - if (spacingAfter != 0) { - jo.put("sa", spacingAfter); - } - if (lineSpacing != 0) { - jo.put("ls", lineSpacing); - } - } - - /** - * 获取字体 - */ - public FRFont getFRFont() { - if (this.frFont == null) { - this.frFont = FRContext.getDefaultValues().getFRFont(); - } - return this.frFont; - } - - /** - * Gets cell format. - */ - public Format getFormat() { - return this.format; - } - - /** - * Gets background. - */ - public Background getBackground() { - return this.background; - } - - /** - * Gets the type of border to use for the top border of the cell. - * - * @see Constants#LINE_NONE - * @see Constants#LINE_THIN - * @see Constants#LINE_MEDIUM - * @see Constants#LINE_DASH - * @see Constants#LINE_HAIR - * @see Constants#LINE_HAIR2 - * @see Constants#LINE_THICK - * @see Constants#LINE_DOUBLE - * @see Constants#LINE_DOT - * @see Constants#LINE_MEDIUM_DASH - * @see Constants#LINE_DASH_DOT - * @see Constants#LINE_MEDIUM_DASH_DOT - * @see Constants#LINE_DASH_DOT_DOT - * @see Constants#LINE_MEDIUM_DASH_DOT_DOT - * @see Constants#LINE_SLANTED_DASH_DOT - */ - public int getBorderTop() { - return this.border_top; - } - - /** - * 获取上边框线的宽度 - */ - public int getBorderTopWidth() { - return GraphHelper.getLineStyleSize(this.getBorderTop()); - } - - /** - * Gets the type of border to use for the left border of the cell. - * - * @see Constants#LINE_NONE - * @see Constants#LINE_THIN - * @see Constants#LINE_MEDIUM - * @see Constants#LINE_DASH - * @see Constants#LINE_HAIR - * @see Constants#LINE_HAIR2 - * @see Constants#LINE_THICK - * @see Constants#LINE_DOUBLE - * @see Constants#LINE_DOT - * @see Constants#LINE_MEDIUM_DASH - * @see Constants#LINE_DASH_DOT - * @see Constants#LINE_MEDIUM_DASH_DOT - * @see Constants#LINE_DASH_DOT_DOT - * @see Constants#LINE_MEDIUM_DASH_DOT_DOT - * @see Constants#LINE_SLANTED_DASH_DOT - */ - public int getBorderLeft() { - return this.border_left; - } - - public int getBorderLeftWidth() { - return GraphHelper.getLineStyleSize(this.getBorderLeft()); - } - - public int getBorderRightWidth() { - return GraphHelper.getLineStyleSize(this.getBorderRight()); - } - - public int getBorderBottomWidth() { - return GraphHelper.getLineStyleSize(this.getBorderBottom()); - } - - /** - * Gets the type of border to use for the bottom border of the cell. - * - * @see Constants#LINE_NONE - * @see Constants#LINE_THIN - * @see Constants#LINE_MEDIUM - * @see Constants#LINE_DASH - * @see Constants#LINE_HAIR - * @see Constants#LINE_HAIR2 - * @see Constants#LINE_THICK - * @see Constants#LINE_DOUBLE - * @see Constants#LINE_DOT - * @see Constants#LINE_MEDIUM_DASH - * @see Constants#LINE_DASH_DOT - * @see Constants#LINE_MEDIUM_DASH_DOT - * @see Constants#LINE_DASH_DOT_DOT - * @see Constants#LINE_MEDIUM_DASH_DOT_DOT - * @see Constants#LINE_SLANTED_DASH_DOT - */ - public int getBorderBottom() { - return this.border_bottom; - } - - /** - * Gets the type of border to use for the right border of the cell. - * - * @see Constants#LINE_NONE - * @see Constants#LINE_THIN - * @see Constants#LINE_MEDIUM - * @see Constants#LINE_DASH - * @see Constants#LINE_HAIR - * @see Constants#LINE_HAIR2 - * @see Constants#LINE_THICK - * @see Constants#LINE_DOUBLE - * @see Constants#LINE_DOT - * @see Constants#LINE_MEDIUM_DASH - * @see Constants#LINE_DASH_DOT - * @see Constants#LINE_MEDIUM_DASH_DOT - * @see Constants#LINE_DASH_DOT_DOT - * @see Constants#LINE_MEDIUM_DASH_DOT_DOT - * @see Constants#LINE_SLANTED_DASH_DOT - */ - public int getBorderRight() { - return this.border_right; - } - - /** - * Gets the color of border to use for the top border of the cell. - */ - public Color getBorderTopColor() { - return this.border_top_color; - } - - /** - * Gets the color of border to use for the left border of the cell. - */ - public Color getBorderLeftColor() { - return this.border_left_color; - } - - /** - * Gets the color of border to use for the bottom border of the cell. - */ - public Color getBorderBottomColor() { - return this.border_bottom_color; - } - - /** - * Gets the color of border to use for the right border of the cell. - */ - public Color getBorderRightColor() { - return this.border_right_color; - } - - /** - * Gets the type of horizontal alignment for the cell - * - * @see BaseUtils#getAlignment4Horizontal(NewFormStyle style, Object value) - * @see BaseUtils#getAlignment4Horizontal(NewFormStyle style) - * @see Constants#LEFT - * @see Constants#CENTER - * @see Constants#RIGHT - * @deprecated suggest not directly use; - */ - public int getHorizontalAlignment() { - return this.horizontal_alignment; - } - - /** - * Gets the type of vertical alignment for the cell - * - * @see Constants#TOP - * @see Constants#CENTER - * @see Constants#BOTTOM - */ - public int getVerticalAlignment() { - return this.vertical_alignment; - } - - /** - * Gets the text style. - * - * @see NewFormStyle#TEXTSTYLE_WRAPTEXT - * @see NewFormStyle#TEXTSTYLE_SINGLELINE - * @see NewFormStyle#TEXTSTYLE_SINGLELINEADJUSTFONT - * @see NewFormStyle#TEXTSTYLE_MULTILINEADJUSTFONT - */ - public int getTextStyle() { - return textStyle; - } - - /** - * Gets the value of verticalText - */ - public int getVerticalText() { - return this.verticalText; - } - - /** - * Gets the value of textDirection - */ - public int getTextDirection() { - return this.textDirection; - } - - /** - * Gets the degree of rotation for the text in the cell - * (between -90 and 90 degrees). - */ - public int getRotation() { - return this.rotation; - } - - /** - * Gets the image layout - * - * @return the image layout - * @see Constants#IMAGE_TILED - * @see Constants#IMAGE_CENTER - * @see Constants#IMAGE_EXTEND - */ - public int getImageLayout() { - return imageLayout; - } - - /** - * get indentation value - */ - public int getPaddingLeft() { - return this.paddingLeft; - } - - /** - * get indentation value - */ - public int getPaddingRight() { - return this.paddingRight; - } - - /** - * @return the spacingBefore - */ - public byte getSpacingBefore() { - return spacingBefore; - } - - /** - * @return the spacingAfter - */ - public byte getSpacingAfter() { - return spacingAfter; - } - - /** - * @return the lineSpacing - */ - public byte getLineSpacing() { - return lineSpacing; - } - - - /** - * 如果单元格内容不为数字或者字符串的时候使用静态数据 - * - * @return - */ - public String getContentClsCss() { - return contentClsCss; - } - - /** - * 若value为数字或字符串需要判断一下是否可以转换为数字显示 - * - * @param value - * @return - */ - public String getContentClsCss(Object value) { - return this.contentStyle2class(this.contentStyleCssMap, value); - } - - /** - * getContentStyleCssMap - */ - public Map getContentStyleCssMap() { - return contentStyleCssMap; - } - - /** - * getBorderClsCss - */ - public String getBorderClsCss() { - return borderClsCss; - } - - /** - * getBorderStyleCssMap - */ - public Map getBorderStyleCssMap() { - return borderStyleCssMap; - } - - /** - * contentStyle2class - */ - private String contentStyle2class(Map contentCssMap) { - return contentStyle2class(contentCssMap, null); - } - - protected String contentStyle2class(Map contentCssMap, Object value) { - StringBuilder sb = new StringBuilder(); - sb.append("fh"); - int horizontal_alignment = BaseUtils.getAlignment4Horizontal(this, value); - switch (horizontal_alignment) { - case Constants.CENTER: - sb.append(" tac"); - break; - case Constants.RIGHT: - sb.append(" tar"); - break; - } - switch (this.vertical_alignment) { - case Constants.BOTTOM: - sb.append(" vab"); - break; - case Constants.TOP: - sb.append(" vat"); - break; - } - - if (this.textStyle != NewFormStyle.TEXTSTYLE_WRAPTEXT - && this.textStyle != NewFormStyle.TEXTSTYLE_MULTILINEADJUSTFONT) { - sb.append(" nw"); - } else { - sb.append(" bw"); // alex:只可以用于ie,英文的长单词会被换行分开 - } - - FRFont font = this.getFRFont(); - if (font != null) { - sb.append(font2Class(font, contentCssMap, lineSpacing)); - } - - int lit = this.paddingLeft; - int rit = this.paddingRight; - int tit = this.spacingBefore; - int bit = this.spacingAfter; - //这边的<= 包括下面<>修改的话, 都要做好兼容的 - if (lit <= DEFAULT_PADDING) { - sb.append(" pl" + lit); - } else { - contentCssMap.put("padding-left", lit + "pt"); - } - - if (rit < DEFAULT_PADDING) { - sb.append(" pr" + rit); - } else if (rit > DEFAULT_PADDING) { - contentCssMap.put("padding-right", rit + "pt"); - } - - if (0 < tit && tit <= DEFAULT_PADDING) { - sb.append(" pt" + tit); - } else if (tit > DEFAULT_PADDING) { - contentCssMap.put("padding-top", tit + "pt"); - } - - if (0 < bit && bit <= DEFAULT_PADDING) { - sb.append(" pb" + bit); - } else if (bit > DEFAULT_PADDING) { - contentCssMap.put("padding-bottom", bit + "pt"); - } - - return sb.toString().trim(); - } - - public JSONObject border2JSONObject() throws JSONException { - JSONObject borderJSON = new JSONObject(); - if (checkLeftRightTopBottom4b1()) { - borderJSON.put("b1", true); - } else { - border2JSONObject(borderJSON, border_top, border_top_color, "t"); - border2JSONObject(borderJSON, border_left, border_left_color, "l"); - border2JSONObject(borderJSON, border_bottom, border_bottom_color, "b"); - border2JSONObject(borderJSON, border_right, border_right_color, "r"); - } - return borderJSON; - } - - private void border2JSONObject(JSONObject jo, byte borderStyle, Color borderColor, String position) throws JSONException { - if (borderStyle == Constants.LINE_THIN - && ComparatorUtils.equals(borderColor, Color.black)) { - jo.put(position, new JSONObject().put("w", 1)); - } else { - int bw = BaseUtils.getBorderWidth(borderStyle); - if (bw > 0) { - JSONObject extra = new JSONObject(); - extra.put("w", bw); - if (!ComparatorUtils.equals(borderColor, Color.black)) { - extra.put("c", StableUtils.javaColorToCSSColor(borderColor)); - } - // 留着保持兼容老的app - extra.put("s", borderLine2String(borderStyle)); - // MOBILE-21527 报表设计器设置不同的border后台返回具体的border类型 - extra.put("type", borderStyle); - jo.put(position, extra); - } - } - } - - private String borderLine2String(int borderStyle) { - switch (borderStyle) { - case Constants.LINE_THIN: - case Constants.LINE_SLIM: - return "t"; - case Constants.LINE_MEDIUM: - return "m"; - case Constants.LINE_THICK: - return "tk"; - case Constants.LINE_DOUBLE: - return "de"; - case Constants.LINE_DOT: - return "dt"; - case Constants.LINE_DASH_DOT: - return "dadt"; - case Constants.LINE_DASH_DOT_DOT: - return "ddd"; - default: - return "dash"; - } - } - - /* - * 返回classBuf与styleBuf - */ - private String border2Class(Map borderCssMap) { - StringBuilder sb = new StringBuilder(); - // 简化class - if (checkLeftRightTopBottom4b0()) { - sb.append(" b0"); - return sb.toString().trim(); - } else if (checkLeftRightTopBottom4b1()) { - sb.append(" b1"); - return sb.toString().trim(); - } - - // right - visible_border_css(this.border_right, this.border_right_color, sb, borderCssMap, "r"); - // bottom - visible_border_css(this.border_bottom, this.border_bottom_color, sb, borderCssMap, "b"); - // left - visible_border_css(this.border_left, this.border_left_color, sb, borderCssMap, "l"); - // top - visible_border_css(this.border_top, this.border_top_color, sb, borderCssMap, "t"); - - return sb.toString().trim(); - } - - private boolean checkLeftRightTopBottom4b0() { - return this.border_left == Constants.LINE_NONE && this.border_right == Constants.LINE_NONE - && this.border_top == Constants.LINE_NONE && this.border_bottom == Constants.LINE_NONE; - } - - private boolean checkLeftRightTopBottom4b1() { - return this.border_left == Constants.LINE_THIN && this.border_right == Constants.LINE_THIN - && this.border_top == Constants.LINE_THIN && this.border_bottom == Constants.LINE_THIN - && ComparatorUtils.equals(this.border_left_color, Color.black) - && ComparatorUtils.equals(this.border_right_color, Color.black) - && ComparatorUtils.equals(this.border_top_color, Color.black) - && ComparatorUtils.equals(this.border_bottom_color, Color.black); - } - - private static void visible_border_css( - byte border_style, Color border_color, StringBuilder classBuf, Map borderCssMap, String border_position - ) {// right - if (border_style == Constants.LINE_THIN - && ComparatorUtils.equals(border_color, Color.black)) { - classBuf.append(" b" + border_position + "1"); - } - - int bw = BaseUtils.getBorderWidth(border_style); - if (bw > 0) { - // width - classBuf.append(" b" + border_position + "w" + bw); - - // style - classBuf.append(" " + __border2Class(border_style, border_position)); - - // color - // 细线需要另外处理为 rgba,rgba的边框在chrome上会出现渲染问题 - // 转为 rgb 显示 - if (border_style == Constants.LINE_SLIM) { - borderCssMap.put(_position2Colorcss(border_position), - StableUtils.javaColorToCSSColor(brighter(border_color))); - } else if (ComparatorUtils.equals(border_color, Color.black)) { - classBuf.append(" b" + border_position + "cb"); - } else { - borderCssMap.put(_position2Colorcss(border_position), StableUtils.javaColorToCSSColor(border_color)); - } - } else { - classBuf.append(" b" + border_position + "0"); - } - } - - private static Color brighter(Color ori) { - return new Color(Math.min((int) ((1 - FACTORY_ALPHA) * 255 + FACTORY_ALPHA * ori.getRed()), 255), - Math.min((int) ((1 - FACTORY_ALPHA) * 255 + FACTORY_ALPHA * ori.getGreen()), 255), - Math.min((int) ((1 - FACTORY_ALPHA) * 255 + FACTORY_ALPHA * ori.getBlue()), 255), - 255); - } - - private static String _position2Colorcss(String border_position) { - if (ComparatorUtils.equals(border_position, "r")) { - return "border-right-color"; - } else if (ComparatorUtils.equals(border_position, "b")) { - return "border-bottom-color"; - } else if (ComparatorUtils.equals(border_position, "l")) { - return "border-left-color"; - } else if (ComparatorUtils.equals(border_position, "t")) { - return "border-top-color"; - } else { - return "border-color"; - } - } - - private static String __border2Class(int borderStyle, String d) { - switch (borderStyle) { - case Constants.LINE_SLIM: - return "b" + d + "ss"; - case Constants.LINE_THIN: - return "b" + d + "ss"; - case Constants.LINE_MEDIUM: - return "b" + d + "ss"; - case Constants.LINE_THICK: - return "b" + d + "ss"; - case Constants.LINE_DOUBLE: - return "b" + d + "sd"; - case Constants.LINE_DOT: - return "b" + d + "sdo"; - case Constants.LINE_DASH_DOT: - return "b" + d + "sdo"; - case Constants.LINE_DASH_DOT_DOT: - return "b" + d + "sdo"; - default: - return "b" + d + "sda"; - } - } - - private static String font2Class(Font font, Map cssMap, byte lineSpacing) { - StringBuilder sb = new StringBuilder(); - if (font.isBold()) { - sb.append(" fwb"); - } - if (font.isItalic()) { - sb.append(" fsi"); - } - String fontName = font.getName(); - String cls = (String) getclsFontFamily().get(fontName); - if (cls == null) { - // REPORT-25741 部分字体需要加引号才能识别 - cssMap.put("font-family", "'" + fontName + "'"); - } else if (!ComparatorUtils.equals(cls, "fnss")) { // alex:font-family:SimSun写在fh里面了 - sb.append(" " + cls); - } - float size = font.getSize2D(); - if (AssistUtils.equals(size, N_SIZE)) { // alex:font-size:9pt写在fh里面 - } else if (size >= MIN_SIZE && size <= MAX_SIZE) { - size = Utils.round5(size); - sb.append(" f" + String.valueOf(size).replace('.', '-')); - } else { - cssMap.put("font-size", font.getSize2D() + "pt"); - } - - if (lineSpacing != 0) { - // carl:直接在这里添上line-height - //cellFM.getHeight() 不能简单的 *(4/3)进行转换,数值不对 - FontMetrics cellFM = GraphHelper.getFontMetrics(FRFont.getInstance(font).applyResolutionNP(Constants.FR_PAINT_RESOLUTION)); - cssMap.put("line-height", (int) (cellFM.getHeight() + lineSpacing * LINE_HEIGHT_FIX / LINE_HEIGHT_FIX2) + "px"); - } - - font2ClassOnFRFont(font, cssMap, sb); - - return sb.toString(); - } - - private static void font2ClassOnFRFont(Font font, Map cssMap, StringBuilder sb) { - if (font instanceof FRFont) { - if (((FRFont) font).isStrikethrough()) { - if (((FRFont) font).getUnderline() != Constants.LINE_NONE) { - sb.append(" tdstu"); - } else { - sb.append(" tdst"); - } - } else { - if (((FRFont) font).getUnderline() != Constants.LINE_NONE) { - sb.append(" tdu"); - } - } - if (((FRFont) font).isSubscript()) { - sb.append(" suber"); - } else if (((FRFont) font).isSuperscript()) { - sb.append(" super"); - } - if (((FRFont) font).isShadow()) { - sb.append(" shadow"); - } - Color color = ((FRFont) font).getForeground(); - if (!ComparatorUtils.equals(color, Color.black) && color != null) { - cssMap.put("color", StableUtils.javaColorToCSSColor(color)); - } - } - } - - - private transient int hashCode = -1; - - /** - * 哈希码 - * - * @return 哈希值h - */ - public int hashCode() { - - if (hashCode == -1) { - //因为format和非ColorBackground的Background并不是唯一的(也就是说即使equals但hashCode也会不一样),所以不放在hashCode的计算里面 - int code = this.border_top ^ this.border_bottom ^ this.border_left ^ this.border_right ^ - this.border_top_color.hashCode() ^ this.border_bottom_color.hashCode() ^ - this.border_left_color.hashCode() ^ this.border_right_color.hashCode() ^ - this.horizontal_alignment ^ this.imageLayout ^ this.verticalText ^ - this.paddingLeft ^ this.paddingRight ^ this.rotation ^ this.textDirection ^ this.textStyle ^ this.vertical_alignment; - - if (frFont != null) { - code ^= frFont.hashCode(); - } - if (background != null) { - code = background.fixHashCode(code); - } - hashCode = code; - } - return hashCode; - } - - /** - * Equals. - */ - public boolean equals(Object object) { - if (object == this) { - return true; - } - if (!(object instanceof NewFormStyle)) { - return false; - } - - NewFormStyle newStyle = (NewFormStyle) object; - - //由于java中所有的Format都实现了equals()方法,这里可以直接来比较. - return ComparatorUtils.equals(newStyle.getFormat(), this.getFormat()) && - ComparatorUtils.equals(newStyle.getFRFont(), this.getFRFont()) && - ComparatorUtils.equals(newStyle.getBackground(), this.getBackground()) && - - newStyle.getBorderTop() == this.getBorderTop() && - newStyle.getBorderLeft() == this.getBorderLeft() && - newStyle.getBorderBottom() == this.getBorderBottom() && - newStyle.getBorderRight() == this.getBorderRight() && - - ComparatorUtils.equals(newStyle.getBorderTopColor(), this.getBorderTopColor()) && - ComparatorUtils.equals(newStyle.getBorderLeftColor(), this.getBorderLeftColor()) && - ComparatorUtils.equals(newStyle.getBorderBottomColor(), this.getBorderBottomColor()) && - ComparatorUtils.equals(newStyle.getBorderRightColor(), this.getBorderRightColor()) && - - BaseUtils.getAlignment4Horizontal(newStyle) == BaseUtils.getAlignment4Horizontal(this) && - newStyle.getVerticalAlignment() == this.getVerticalAlignment() && - newStyle.getTextStyle() == this.getTextStyle() && - - //james verticalText - newStyle.getVerticalText() == this.getVerticalText() && - newStyle.getTextDirection() == this.getTextDirection() && - newStyle.getRotation() == this.getRotation() && - newStyle.getImageLayout() == this.getImageLayout() && - - // alex padding - newStyle.getPaddingLeft() == this.getPaddingLeft() && - newStyle.getPaddingRight() == this.getPaddingRight() && - - //间距 - newStyle.getSpacingBefore() == this.getSpacingBefore() && - newStyle.getSpacingAfter() == this.getSpacingAfter() && - newStyle.getLineSpacing() == this.getLineSpacing(); - } - - /** - * Clone. - */ - public Object clone() throws CloneNotSupportedException { - return this; - } - - protected Object readResolve() throws InvalidObjectException { - if (this.getClass() != NewFormStyle.class) { - throw new InvalidObjectException("subclass didn't correctly implement readResolve"); - } - - Object res = initializeStyle.get(this); - //alex:从ObjectInputStream生成的Object可能不存在于全局的map中,可能为null - if (res == null) { - res = this; - initializeStyle.put(this, res); - } - - return res; - } - - /** - * 画单元格的Value - *

- * 通过width, height方式画 - */ - public static void paintContent(Graphics2D g2d, Object value, NewFormStyle style, int width, int height, int resolution) { - // kunsnat: 添加判断width和height. 是否有必要继续paint, @bug0006854, 增加了混乱的字符. - if (value == null || width == 0 || height == 0) { - return; - } - - if (style == null) { - //peter:获取默认的Style. - style = NewFormStyle.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_CENTER); - } - - if (value instanceof BaseFormula) { - value = ((BaseFormula) value).getResult(); - } - - if (value instanceof Painter) { - // TODO 弹出界面然后 esc bug.. - ((Painter) value).paint(g2d, width, height, resolution, style); - } else if (value instanceof ImageProvider) { - paintImageContent(g2d, ((ImageProvider) value).getImage(), style, width, height, resolution); - } else if (value instanceof Image) { - paintImageContent(g2d, (Image) value, style, width, height, resolution); - } else { - //默认Paint String - String text = valueToText(value, style.getFormat()); - paintCellStyleString(g2d, width, height, text, style, resolution); - } - } - - public static void paintImageContent(Graphics2D g2d, Image value, NewFormStyle style, int width, int height, int resolution) { - int imageLayout = CoreGraphHelper.changeImageLayout4Draw(value, style.getImageLayout(), width, height); - - //这边做scale的目的是为了在导出图片以及以图片方式打印时,根据不同的resolution调整对应的dpi - int defaultResolution = Constants.DEFAULT_WEBWRITE_AND_SCREEN_RESOLUTION; - double scale = resolution * 1d / defaultResolution; - width = (int) (width / scale); - height = (int) (height / scale); - g2d.scale(scale, scale); - - GraphHelper.paintImage(g2d, width, height, value, imageLayout, - style.getHorizontalAlignment(), style.getVerticalAlignment(), -1, -1); - //最后把画板改回来 - g2d.scale(defaultResolution * 1d / resolution, defaultResolution * 1d / resolution); - } - - /** - * 画单元格的Value - *

- * 通过PaintRectangle + ClipRectangle画 - */ - public static void paintContent(Graphics2D g2d, Object value, int resolution, NewFormStyle style, Rectangle paintRectangle, Rectangle clipRectangle) { - Shape oldClip = g2d.getClip(); - g2d.translate(paintRectangle.getX(), paintRectangle.getY()); - g2d.clip(clipRectangle); // kunsnat: 这些clip 都没有考虑边框啊!!! 所有图表的边框压缩到里面去了. - - paintContent(g2d, value, style, paintRectangle.width, paintRectangle.height, resolution); - - g2d.translate(-paintRectangle.getX(), -paintRectangle.getY()); - g2d.setClip(oldClip); - } - - /** - * 画背景 - *

- * 通过width, height方式画 - */ - public static void paintBackground(Graphics2D g2d, NewFormStyle style, double width, double height) { - if (style == null) {// 还是需要检查一下的,假如DefaultCellStyle拥有Border就需要Paint了. - return; - } - - // paint background. - Background background = style.getBackground(); - if (background == null) { - return; - } - - background.layoutDidChange((int) width, (int) height); - synchronized (tempRectangle2D) { - tempRectangle2D.setRect(0, 0, width, height); - background.paint(g2d, tempRectangle2D); - } - } - - /** - * 画单元格的背景 - *

- * 通过PaintRectangle + ClipRectangle画 - */ - public static void paintBackground(Graphics2D g2d, NewFormStyle style, Rectangle paintRectangle, Rectangle clipRectangle) { - if (style == null) { - //peter:获取默认的Style. - style = NewFormStyle.DEFAULT_STYLE; - } - Shape oldClip = g2d.getClip(); - g2d.translate(paintRectangle.getX(), paintRectangle.getY()); - g2d.clip(clipRectangle); - Background background = style.getBackground(); - - if (background != null) { - // alex:根据paintRectangle和clipRectangle共同决定Background的PaintRectangle - background.paint(g2d, new Rectangle( - clipRectangle.x, clipRectangle.y, - clipRectangle.width, clipRectangle.height)); - } - g2d.translate(-paintRectangle.getX(), -paintRectangle.getY()); - g2d.setClip(oldClip); - } - - /** - * 画边框 - *

- * 通过width, height方式画 - */ - public static void paintBorder(Graphics2D g2d, NewFormStyle style, double width, double height) { - if (style == null) {// 还是需要检查一下的,假如DefaultCellStyle拥有Border就需要Paint了. - return; - } - - //peter:当是粗线的时候,需要计算尺寸 - double left = 0; - double right = 0; - if (style.getBorderLeft() != Constants.LINE_NONE) { - int borderLeftSize = GraphHelper.getLineStyleSize(style.getBorderLeft()); - left = borderLeftSize / 2; - } - if (style.getBorderRight() != Constants.LINE_NONE) { - int borderRightSize = GraphHelper.getLineStyleSize(style.getBorderRight()); - right = borderRightSize / 2; - } - - double top = 0; - double bottom = 0; - if (style.getBorderTop() != Constants.LINE_NONE) { - int bSize = GraphHelper.getLineStyleSize(style.getBorderTop()); - top = bSize / 2; - } - if (style.getBorderBottom() != Constants.LINE_NONE) { - int bSize = GraphHelper.getLineStyleSize(style.getBorderBottom()); - bottom = bSize / 2; - } - - // paint border - if (style.getBorderTop() != Constants.LINE_NONE) { - g2d.setPaint(style.getBorderTopColor()); - GraphHelper.drawLine(g2d, 0 - left, 0, width + right, 0, style.getBorderTop()); - } - if (style.getBorderLeft() != Constants.LINE_NONE) { - g2d.setPaint(style.getBorderLeftColor()); - GraphHelper.drawLine(g2d, 0, 0 - top, 0, height + bottom, style.getBorderLeft()); - } - if (style.getBorderBottom() != Constants.LINE_NONE) { - g2d.setPaint(style.getBorderBottomColor()); - GraphHelper.drawLine(g2d, 0 - left, height, width + right, height, style.getBorderBottom()); - } - if (style.getBorderRight() != Constants.LINE_NONE) { - g2d.setPaint(style.getBorderRightColor()); - GraphHelper.drawLine(g2d, width, 0 - top, width, height + bottom, style.getBorderRight()); - } - } - - /** - * 画单元格的边框 - *

- * 通过PaintRectangle + ClipRectangle画边框 - */ - public static void paintBorder(Graphics2D g2d, NewFormStyle style, Rectangle paintRectangle, Rectangle clipRectangle) { - //单元格行高列宽=0时, 不需要绘制边框 - if (paintRectangle.width == 0 || paintRectangle.height == 0) { - return; - } - g2d.translate(paintRectangle.getX(), paintRectangle.getY()); - - Rectangle realPaintRect = new Rectangle(0, 0, - paintRectangle.width, paintRectangle.height); - //peter:需要判断的因为clipRectangle极可能不是null. - if (clipRectangle != null) { - realPaintRect = realPaintRect.intersection(clipRectangle); - } - g2d.translate(realPaintRect.getX(), realPaintRect.getY()); - - if (style == null) {// 还是需要检查一下的,假如DefaultCellStyle拥有Border就需要Paint了. - //peter:获取默认的Style. - style = NewFormStyle.DEFAULT_STYLE; - } - - paintBorder(g2d, style, realPaintRect.getWidth(), realPaintRect.getHeight()); - - // 返回Translate - g2d.translate(-realPaintRect.getX(), -realPaintRect.getY()); - g2d.translate(-paintRectangle.getX(), -paintRectangle.getY()); - } - - /** - * 转化成文本 - * - * @param value 带转化的对象 - * @param format 格式g - * @return 字符串z - */ - public static String valueToText(Object value, Format format) { - //需要画的值,主要是把公式里面的值拿出来 - Object valueToPaint = value; - String text = null; - - String checkInfinity = StableUtils.checkInfinity(value); - if (StringUtils.isNotEmpty(checkInfinity)) { - return checkInfinity; - } - - if (value != null) { - if (value instanceof BaseFormula) { - BaseFormula formula = (BaseFormula) value; - if (StableUtils.isNull(formula.getResult())) { - return StringUtils.EMPTY;// BUG4788,应该显示空字符串 - } else { - valueToPaint = formula.getResult(); - } - } else if (value instanceof Clob) { - valueToPaint = DataBaseUtils.clob2String((Clob) value); - } - - if (format != null) { - format = FormatRepository.getInstance().getLocalFormat(format); - if (format instanceof DateFormat) {// Date. - text = valueInDateFormat((DateFormat) format, valueToPaint); - } else if (format instanceof NumberFormat) {// Number. - text = valueInNumberFormat(format, valueToPaint); - } else { - try { - text = format.format(valueToPaint); - } catch (Exception exp) { - text = Utils.objectToString(valueToPaint); - } - } - } else - text = Utils.objectToString(valueToPaint); - } else { - text = StringUtils.EMPTY; - } - - return text; - } - - protected static String valueInNumberFormat(Format format, Object valueToPaint) { - Number number = GeneralUtils.objectToNumberReturnNull(valueToPaint); - if (number != null) { - try { - if (format instanceof CoreDecimalFormat) { - //数字类型的要roundup一下, 默认会逢5奇进偶不进, 62.325->62.33 - return ((CoreDecimalFormat) format).formatRoundingModeUp(number); - } - //62.325->62.32 - return format.format(number); - } catch (Exception ignore) { - } - } - return Utils.objectToString(valueToPaint); - } - - private static String valueInDateFormat(DateFormat format, Object valueToPaint) { - - String result; - Date date2Format = tryGet(format, valueToPaint); - if (date2Format == null) { - date2Format = DateUtils.object2Date(valueToPaint, true); - } - if (date2Format != null) { - result = format.format(date2Format); - } - /* - * alex:如果date2Format为null,就是说valueToPaint不能转换成日期型,那么就直接画valueToPaint的字符串 - * 为什么必须要画valueToPaint的字符串呢?见bug0004566 - * 因为在Grid里面直接写=today(),并设置format为日期,如果不画,就一片空白,什么都看不到了 - */ - else { - result = Utils.objectToString(valueToPaint); - } - - return result; - } - - @Nullable - private static Date tryGet(DateFormat format, Object valueToPaint) { - - Date date2Format = null; - // 先用format来生成日期啊 - if (valueToPaint instanceof Date) { - date2Format = (Date) valueToPaint; - } else { - try { - date2Format = format.parse(GeneralUtils.objectToString(valueToPaint)); - } catch (Exception e) { - // nothing - } - } - return date2Format; - } - - /** - * Paint string according to Style. - */ - public static void paintCellStyleString2(Graphics2D g2d, int width, int height, String text, Style style, int resolution) { - if (StringUtils.isBlank(text)) { - return; - } - Paint oldPaint = g2d.getPaint(); - if (style == null) { - style = NewFormStyle.DEFAULT_STYLE; - } - Font rfont = BaseUtils.getStyleFont(g2d, style, resolution); - if (style.getRotation() != 0 && style.getVerticalText() == NewFormStyle.HORIZONTALTEXT) { - BaseUtils.drawStringStyleInRotation(g2d, width, height, text, style, resolution); - } else { - if (style.getTextStyle() == NewFormStyle.TEXTSTYLE_SINGLELINEADJUSTFONT - || style.getTextStyle() == NewFormStyle.TEXTSTYLE_MULTILINEADJUSTFONT) { - List lineTextList = BaseUtils.getLineTextList(text, style, rfont, height, width, resolution); - if (width <= 0 || lineTextList.isEmpty()) { - return; - } - int textAscent = g2d.getFontMetrics().getAscent(); - int textHeight = g2d.getFontMetrics().getHeight(); - - int textY = 0; - int textAllHeight = textHeight * lineTextList.size(); - double spacingBefore = PT.pt2pix(style.getSpacingBefore(), resolution); - double spacingAfter = PT.pt2pix(style.getSpacingAfter(), resolution); - double lineSpacing = PT.pt2pix(style.getLineSpacing(), resolution); - //james:加上间距,WORD中的行间距是从第一行文本的上面一行就算的,所以行间距形成的空隙与文本行数相同 - textAllHeight += spacingBefore + spacingAfter + lineSpacing * lineTextList.size(); - if (style.getVerticalAlignment() == Constants.CENTER) { - if (height > textAllHeight) {// 如果所有文本的高度小于当前可以绘区域的高度,就从0开始画字符. - textY = (height - textAllHeight) / 2; - } - } else if (style.getVerticalAlignment() == Constants.BOTTOM) { - textY = height - textAllHeight; - } - textY += textAscent;// 在绘画的时候,必须添加Ascent的高度. - textY += spacingBefore + lineSpacing;//james:加上"段前间距"+“行间距” - if (style.getTextStyle() == NewFormStyle.TEXTSTYLE_SINGLELINEADJUSTFONT) {// 通过自动调整字体显示所有的信息调整Font来显示所有的字符 - ContentLineGroup contentLineGroup = singleLineAdjustFont(style, lineTextList, width, height, g2d, resolution, true); - _drawContentLineGroup(contentLineGroup, g2d, textY, height, width, BaseUtils.getAlignment4Horizontal(style, text)); - } else if (style.getTextStyle() == NewFormStyle.TEXTSTYLE_MULTILINEADJUSTFONT) { - ContentLineGroup contentLineGroup = mulitiLineAdjustFont(style, lineTextList, width, height, g2d, resolution, true); - _drawContentLineGroup(contentLineGroup, g2d, textY, height, width, BaseUtils.getAlignment4Horizontal(style, text)); - } - } else { - BaseUtils.drawStringStyleInRotation(g2d, width, height, text, style, resolution); - } - } - g2d.setPaint(oldPaint); - } - - - - private static void _drawContentLineGroup( - ContentLineGroup contentLineGroup, Graphics2D g2d, - int textY, int height, int width, int horizontalAlignment - ) { - Style style = contentLineGroup.style; - - Font oldFRFont = g2d.getFont(); - g2d.setFont(style.getFRFont()); - if (style.getVerticalAlignment() == Constants.TOP) { - textY = 0; - } else if (style.getVerticalAlignment() == Constants.CENTER) { - if (height > contentLineGroup.totalHeight()) {// 如果所有文本的高度小于当前可以绘区域的高度,就从0开始画字符. - textY = (height - contentLineGroup.totalHeight()) / 2; - } else { - textY = 0; - } - } else if (style.getVerticalAlignment() == Constants.BOTTOM) { - textY = height - contentLineGroup.totalHeight(); - } - textY += g2d.getFontMetrics().getAscent();// 在绘画的时候,必须添加Ascent的高度. - - for (int i = 0; i < contentLineGroup.newLineTextList.size(); i++) { - double textX = style.getPaddingLeft(); - int textWidth = GraphHelper.getFontMetrics(style.getFRFont()).stringWidth((String) contentLineGroup.newLineTextList.get(i)); - if (horizontalAlignment == Constants.CENTER) { - textX = (width - textWidth - style.getPaddingRight()) / 2.0; - } else if (horizontalAlignment == Constants.RIGHT) { - textX = width - style.getPaddingRight() - textWidth; - } else if (horizontalAlignment == Constants.DISTRIBUTED) {// added by KevinWang - } - - if (horizontalAlignment == Constants.DISTRIBUTED) { - String lineText = (String) contentLineGroup.newLineTextList.get(i);// 分行显示时第i行的内容,但是也可能单行 - double charSpace = (width - style.getPaddingLeft() - style.getPaddingRight() - - g2d.getFontMetrics().charWidth(lineText.charAt(lineText.length() - 1))) - / (lineText.length() - 1); - for (int charIndex = 0; charIndex < lineText.length(); charIndex++) { - char tmpChar = lineText.charAt(charIndex);//取出一个字符待显示 - String tmpString = new String((new StringBuffer()).append(tmpChar));// 将其包装成string形式 - double charX = style.getPaddingLeft() + charIndex * charSpace; - GraphHelper.drawString(g2d, tmpString, charX, textY);//显示 - } - } else { - GraphHelper.drawString(g2d, (String) contentLineGroup.newLineTextList.get(i), textX, textY); - } - textY += contentLineGroup.newTextHeight; - } - g2d.setFont(oldFRFont); - } - - /* - * 通过自动调整字体显示所有的信息调整Font来显示所有的字符 - */ - private static ContentLineGroup singleLineAdjustFont(Style style, List lineTextList, int width, int height, Graphics2D g2d, int resolution, boolean fontScale) { - FRFont newFRFont = (FRFont) style.getFRFont().applyResolutionNP(resolution); - - int maxTextWidth = 0; - FontMetrics oriFontMetrics = GraphHelper.getFontMetrics(newFRFont); - int maxTextHeight = oriFontMetrics.getHeight() * lineTextList.size(); - String examle_text = ""; - for (int i = 0; i < lineTextList.size(); i++) { - if (oriFontMetrics.stringWidth((String) lineTextList.get(i)) > maxTextWidth) { - examle_text = (String) lineTextList.get(i); - maxTextWidth = oriFontMetrics.stringWidth((String) lineTextList.get(i)); - } - } - - if (maxTextWidth > 0 || maxTextHeight > 0) { // 只有当大于0时才改变字体大小 - // 调整宽度和高度 - if (maxTextWidth > (width - style.getPaddingLeft() - style.getPaddingRight()) || maxTextHeight > height) { - while (newFRFont.getSize() > 1) { - newFRFont = newFRFont.applySize((float) newFRFont.getSize() - 1); - maxTextWidth = GraphHelper.getFontMetrics(newFRFont).stringWidth(examle_text); - maxTextHeight = GraphHelper.getFontMetrics(newFRFont).getHeight() * lineTextList.size(); - - // 由于Font的变化单位是1, 所以必须这么找最适合的 Font - if (maxTextWidth <= (width - style.getPaddingLeft() - style.getPaddingRight()) && maxTextHeight <= height) { - break; - } - } - } - } - - FRFont returnFont = style.getFRFont().applySize(fontScale ? newFRFont.getSize2D() : FRFont.convResolution(newFRFont.getSize2D(), resolution)); - return new ContentLineGroup(style.deriveFRFont(returnFont), lineTextList, GraphHelper.getFontMetrics(newFRFont, g2d).getHeight()); - } - - /* - * 多行显示(调整字体大小),即固定单元格高和框,改变字体大小使适应。 - */ - private static ContentLineGroup mulitiLineAdjustFont(Style style, List lineTextList, int width, int height, Graphics2D g2d, int resolution, boolean fontScale) { - FRFont newFRFont = (FRFont) style.getFRFont().applyResolutionNP(resolution); - List newLineTextList; - NewFormStyle tmpStyle = NewFormStyle.DEFAULT_STYLE; - tmpStyle = tmpStyle.deriveTextStyle(NewFormStyle.TEXTSTYLE_WRAPTEXT); - int newTextHeight = GraphHelper.getFontMetrics(newFRFont, g2d).getHeight(); - - newLineTextList = resovleLineTextListByStyle(newFRFont, lineTextList, tmpStyle, width, resolution); - - if (newLineTextList.size() * newTextHeight > height) { - while (newFRFont.getSize() > 1) { - newFRFont = newFRFont.applySize((float) newFRFont.getSize() - 1); - newLineTextList = resovleLineTextListByStyle(newFRFont, lineTextList, tmpStyle, width, resolution); - - newTextHeight = GraphHelper.getFontMetrics(newFRFont, g2d).getHeight(); - if (newLineTextList.size() * newTextHeight <= height) { - break; - } - } - } else if (newLineTextList.size() * newTextHeight < height) { - while (newFRFont.getSize() < MAX_FONT_SIZE) { // _denny: 设定字体最大为100 - newFRFont = newFRFont.applySize((float) newFRFont.getSize() + 1); - - newLineTextList = resovleLineTextListByStyle(newFRFont, lineTextList, tmpStyle, width, resolution); - - newTextHeight = GraphHelper.getFontMetrics(newFRFont, g2d).getHeight(); - if (newLineTextList.size() * newTextHeight > height) { - newFRFont = newFRFont.applySize(newFRFont.getSize() - 1); - - newLineTextList = resovleLineTextListByStyle(newFRFont, lineTextList, tmpStyle, width, resolution); - - newTextHeight = GraphHelper.getFontMetrics(newFRFont, g2d).getHeight(); - break; - } - } - } - - FRFont returnFont = tmpStyle.getFRFont().applySize(fontScale ? newFRFont.getSize2D() : FRFont.convResolution(newFRFont.getSize2D(), resolution)); - tmpStyle.deriveFRFont(returnFont); - - return new ContentLineGroup(tmpStyle, newLineTextList, newTextHeight); - } - - private static List resovleLineTextListByStyle(Font font, List lineTextList, NewFormStyle tmpStyle, int width, int resolution) { - List newLineTextList = new ArrayList(); - - List tmpLineTextList; - for (int i = 0; i < lineTextList.size(); i++) { - tmpLineTextList = BaseUtils.getLineTextList((String) lineTextList.get(i), tmpStyle, font, width, resolution); - for (int j = 0; j < tmpLineTextList.size(); j++) { - newLineTextList.add((String) tmpLineTextList.get(j)); - } - } - - return newLineTextList; - } - - /** - * 修改格子样式 - * - * @param width 宽 k - * @param height 高g - * @param text 文本w - * @param style 样式y - * @param resolution 转化率z - * @return 样式 y - */ - public static Style modCellStyleString(int width, int height, String text, Style style, int resolution) { - List lineTextList = BaseUtils.getLineTextList(text, style, null, height, width, resolution); - if (style.getTextStyle() == NewFormStyle.TEXTSTYLE_SINGLELINEADJUSTFONT) { - style = singleLineAdjustFont(style, lineTextList, width, height, null, resolution, false).style; - } else if (style.getTextStyle() == NewFormStyle.TEXTSTYLE_MULTILINEADJUSTFONT) { - style = mulitiLineAdjustFont(style, lineTextList, width, height, null, resolution, false).style; - } - - return style; - } -} diff --git a/designer-form/src/main/java/com/fr/design/fit/common/NewUIModeAutoChangeLine.java b/designer-form/src/main/java/com/fr/design/fit/common/NewUIModeAutoChangeLine.java new file mode 100644 index 000000000..0037c738d --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/fit/common/NewUIModeAutoChangeLine.java @@ -0,0 +1,20 @@ +package com.fr.design.fit.common; + +import com.fr.base.DefaultAutoChangeLine; +import com.fr.base.Style; +import com.fr.stable.unit.UNIT; + +import java.awt.Font; +import java.util.List; + +public class NewUIModeAutoChangeLine extends DefaultAutoChangeLine { + @Override + public List textAutoChangeLine(String text, Font font, Style style, UNIT unitWidth, int resolution) { + return autoChangeLine(text, font, style, unitWidth, resolution); + } + + protected double calculateShowWidth(double paintWidth, Style style, int resolution) { + return paintWidth - style.getPaddingLeft() - style.getPaddingRight() - style.getBorderLeftWidth(); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/fit/common/NewUIModeRotationDraw.java b/designer-form/src/main/java/com/fr/design/fit/common/NewUIModeRotationDraw.java new file mode 100644 index 000000000..3e0b06721 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/fit/common/NewUIModeRotationDraw.java @@ -0,0 +1,69 @@ +package com.fr.design.fit.common; + +import com.fr.base.BaseUtils; +import com.fr.base.DefaultRotationTextDrawProvider; +import com.fr.base.GraphHelper; +import com.fr.base.Style; +import com.fr.design.mainframe.PX; +import com.fr.stable.Constants; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.util.List; + +public class NewUIModeRotationDraw extends DefaultRotationTextDrawProvider { + @Override + public void drawRotationText(Graphics2D g2d, String text, Style style, Font rfont, int width, int height, int horizontalAlignment, int resolution) { + FontMetrics cellFM = GraphHelper.getFontMetrics(rfont); + List lineTextList = BaseUtils.getLineTextList(text, style, rfont, height, width, resolution, new NewUIModeAutoChangeLine()); + drawRotationText(g2d, lineTextList, style, cellFM, width, height, horizontalAlignment, resolution); + } + + + protected int calculateTextWidth(int width, Style style) { + return width - style.getPaddingRight(); + } + + protected double calculateTextX(Style style, int width, int textWidth, int horizontalAlignment, int resolution) { + double textX = padding2PixExcludeRight(style.getPaddingLeft(), resolution); + if (horizontalAlignment == Constants.CENTER) { + textX += (width - textWidth - textX) / 2f; + } else if (horizontalAlignment == Constants.RIGHT) { + textX = width - style.getPaddingRight() - textWidth; + } + return textX; + } + + protected int toPXWithResolution(double pt, int resolution) { + return (int) PX.toPixWithResolution(pt, resolution); + } + + protected double padding2PixExcludeRight(int padding, int resolution) { + return PX.toPixWithResolution(padding, resolution); + } + + protected int calculateTextY(Style style, int height, int textHeight, int textAscent, List lineTextList, int resolution) { + // 计算Y的高度. + int textY = 0; + int textAllHeight = textHeight * lineTextList.size(); + double spacingBefore = toPXWithResolution(style.getSpacingBefore(), resolution); + double spacingAfter = toPXWithResolution(style.getSpacingAfter(), resolution); + double lineSpacing = toPXWithResolution(style.getLineSpacing(), resolution); + textAllHeight += spacingBefore + spacingAfter + lineSpacing * lineTextList.size(); + if (style.getVerticalAlignment() == Constants.TOP) { + } else if (style.getVerticalAlignment() == Constants.CENTER) { + if (height > textAllHeight) {// 如果所有文本的高度小于当前可以绘区域的高度,就从0开始画字符. + textY = (height - textAllHeight) / 2; + } + } else if (style.getVerticalAlignment() == Constants.BOTTOM) { + if (height > textAllHeight) { + textY = height - textAllHeight; + } + } + textY += textAscent;// 在绘画的时候,必须添加Ascent的高度. + textY += spacingBefore + lineSpacing;//james:加上"段前间距"+“行间距” + return textY; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/fit/common/PaintUtils.java b/designer-form/src/main/java/com/fr/design/fit/common/PaintUtils.java deleted file mode 100644 index 8f913a7aa..000000000 --- a/designer-form/src/main/java/com/fr/design/fit/common/PaintUtils.java +++ /dev/null @@ -1,835 +0,0 @@ -/* - * Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved. - */ -package com.fr.design.fit.common; - -import com.fr.base.AutoChangeLineAndDrawManager; -import com.fr.base.BaseFormula; -import com.fr.base.BaseUtils; -import com.fr.base.GraphHelper; -import com.fr.base.ImageProvider; -import com.fr.base.Painter; -import com.fr.base.Style; -import com.fr.base.Utils; -import com.fr.base.background.ColorBackground; -import com.fr.base.chart.BaseChartCollection; -import com.fr.base.chart.result.WebChartIDInfo; -import com.fr.code.BarcodeImpl; -import com.fr.code.bar.BarcodeException; -import com.fr.code.bar.core.BarCodeUtils; -import com.fr.code.bar.core.BarcodeAttr; -import com.fr.data.DataUtils; -import com.fr.data.PresentationType; -import com.fr.data.condition.ListCondition; -import com.fr.file.ResultChangeWhenExport; -import com.fr.form.ui.Widget; -import com.fr.general.Background; -import com.fr.general.ComparatorUtils; -import com.fr.general.FRFont; -import com.fr.general.ImageWithSuffix; -import com.fr.log.FineLoggerFactory; -import com.fr.plugin.ExtraClassManager; -import com.fr.report.cell.CellElement; -import com.fr.report.cell.FloatElement; -import com.fr.report.cell.TemplateCellElement; -import com.fr.report.cell.cellattr.CellExpandAttr; -import com.fr.report.cell.cellattr.CellGUIAttr; -import com.fr.report.cell.cellattr.core.CellUtils; -import com.fr.report.cell.cellattr.core.ResultSubReport; -import com.fr.report.cell.cellattr.core.group.DSColumn; -import com.fr.report.core.Html2ImageUtils; -import com.fr.report.core.ReportUtils; -import com.fr.script.Calculator; -import com.fr.stable.Constants; -import com.fr.stable.CoreConstants; -import com.fr.stable.StringUtils; -import com.fr.stable.bridge.ObjectHolder; -import com.fr.stable.fun.AutoChangeLineAndDrawProcess; -import com.fr.stable.fun.FontProcessor; -import com.fr.stable.html.Tag; -import com.fr.stable.unit.FU; -import com.fr.stable.unit.PT; -import com.fr.stable.unit.UNIT; -import com.fr.stable.web.Repository; - -import javax.swing.ImageIcon; -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.Paint; -import java.awt.Rectangle; -import java.awt.font.TextAttribute; -import java.awt.geom.GeneralPath; -import java.awt.image.BufferedImage; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; - -/** - * The util for paint. - */ -public class PaintUtils { - // Add by Denny - public static final int CELL_MARK_SIZE = 6; - public static final Color CELL_HIGHT_LIGHT_MARK_COLOR = new Color(255, 0, 55); - public static final Color CELL_PRESENT_MARK_COLOR = new Color(0, 255, 200); - public static final Color CELL_PAGINATION_MARK_COLOR = new Color(55, 255, 0); - public static final Color CELL_RESULT_MARK_COLOR = new Color(200, 0, 255); - public static final Color CELL_CONDITION_FILTER_MARK_COLOR = new Color(255, 200, 0); - public static final Color CELL_PARAMETER_FILTER_MARK_CONLR = new Color(0, 55, 255); - - public static final Color CELL_DIRECTION_MARK_COLOR = Color.gray; - private static final int UNIT_SIZE = 4; - - //原值是15,矩形线条会缺失,加1px绘制没问题。这地方有水印,但是貌似不是水印影响,未找到线条被挡住的原因 - private static final int WIDGET_WIDTH = 16; - private static final int WIDGET_HEIGHT = 16; - - // Suppresses default constructor, ensuring non-instantiability. - private PaintUtils() { - } - - // font attributes map cache - private static Hashtable fontAttributeMapCache = new Hashtable(); - - /* - * 用于在Grid里面画CellElement的Content + Background - * - * 不画Border,是因为在Grid里面先画所有单元格的Content + Background,再画所有单元格的Border(peter认为这可以提高速度) - */ - public static void paintGridCellContent(Graphics2D g2d, TemplateCellElement cell, int width, int height, int resolution) { - int cell_mark_size = CELL_MARK_SIZE; - // denny_Grid - // 左上角: 条件高亮, 形态 - int leftUpCount = 0; - int rightUpCount = 0; - int leftDownCount = 0; - GraphHelper.applyRenderingHints(g2d); - if (paintHighlightGroupMarkWhenExsit(g2d, cell, leftUpCount)) { - leftUpCount++; - } - if (paintPresentMarkWhenExsit(g2d, cell, leftUpCount)) { - leftUpCount++; - } - if (paintPaginationMarkWhenExsit(g2d, cell, width, rightUpCount)) { - rightUpCount++; - } - paintWidgetMarkWhenExsit(g2d, cell, width, height); - paintExpandMarkWhenExsit(g2d, cell); - Object value = cell.getValue(); - if (value == null) {// 先判断是否是空. - return; - } - if (paintResultMarkWhenExsit(g2d, value, width, rightUpCount)) { - rightUpCount++; - } - - if (paintDSColumnParametermarkWhenExsit(g2d, value, height, leftDownCount)) { - leftDownCount++; - } - - if (paintDSColumnConditionmarkWhenExsit(g2d, value, height, leftDownCount)) { - leftDownCount++; - } - // 画value,但因为是在Grid里面画,所以画Formula.content - if (value instanceof BaseFormula) { - value = ((BaseFormula) value).getContent(); - } - if (value instanceof ImageWithSuffix) { - value = ((ImageWithSuffix) value).getFineImage(); - } - if (value instanceof BaseChartCollection) { - value = ((BaseChartCollection) value).createResultChartPainterWithOutDealFormula(Calculator.createCalculator(), WebChartIDInfo.createEmptyDesignerInfo(), width, height); - } - // Carl:当是子报表时,在格子里画一个子报表的图 - /* - * alex:TODO 此处在Grid里面画ChartCollection和SubReport都只画一个图表,这种做法,很不雅 - */ - if (value instanceof ResultSubReport) { - value = BaseUtils.readImage("/com/fr/base/images/report/painter/subReport.png"); - GraphHelper.paintImage(g2d, width, height, (Image) value, Constants.IMAGE_CENTER, - BaseUtils.getAlignment4Horizontal(cell.getStyle(), value), cell.getStyle().getVerticalAlignment(), - width > 16 ? 16 : width, height > 16 ? 16 : height); - } else { - renderContent(g2d, value, cell.getStyle(), width, height, resolution); - } - } - - - private static void renderContent(Graphics2D g2d, Object value, Style style, int width, int height, int resolution) { - if (value != null && width != 0 && height != 0) { - if (style == null) { - style = Style.DEFAULT_STYLE.deriveImageLayout(1); - } - - if (value instanceof BaseFormula) { - value = ((BaseFormula) value).getResult(); - } - - if (value instanceof Painter) { - ((Painter)value).paint(g2d, width, height, resolution, style); - } else if (value instanceof ImageProvider) { - Style.paintImageContent(g2d, ((ImageProvider) value).getImage(), style, width, height, resolution); - } else if (value instanceof Image) { - Style.paintImageContent(g2d, (Image) value, style, width, height, resolution); - } else { - String var6 = Style.valueToText(value, style.getFormat()); - NewFormStyle.paintCellStyleString2(g2d, width, height, var6, style, resolution); - } - - } - } - - - private static boolean paintHighlightGroupMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell, int left_up_count) { - if (cell.getHighlightGroup() != null && cell.getHighlightGroup().size() > 0) { - Paint oldPaint = g2d.getPaint(); - - g2d.setPaint(CELL_HIGHT_LIGHT_MARK_COLOR); - GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); - polyline.moveTo(0, 0); - polyline.lineTo(0, CELL_MARK_SIZE); - polyline.lineTo(CELL_MARK_SIZE, 0); - GraphHelper.fill(g2d, polyline); - - g2d.setPaint(oldPaint); - return true; - } - return false; - } - - private static boolean paintPresentMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell, int left_up_count) { - if (cell.getPresent() != null) { - Paint oldPaint = g2d.getPaint(); - - g2d.setPaint(CELL_PRESENT_MARK_COLOR); - GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); - polyline.moveTo(0 + left_up_count * CELL_MARK_SIZE, 0); - polyline.lineTo(0 + left_up_count * CELL_MARK_SIZE, 6); - polyline.lineTo(CELL_MARK_SIZE + left_up_count * CELL_MARK_SIZE, 0); - GraphHelper.fill(g2d, polyline); - - g2d.setPaint(oldPaint); - return true; - } - return false; - } - - private static boolean paintPaginationMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell, int width, int ringt_up_count) { - // 右上角: 标记是否有分页 - if (isRightTopMarker(cell)) { - Paint oldPaint = g2d.getPaint(); - - g2d.setPaint(CELL_PAGINATION_MARK_COLOR); - GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); - polyline.moveTo(width - 1 - ringt_up_count * CELL_MARK_SIZE, 0); - polyline.lineTo(width - 1 - ringt_up_count * CELL_MARK_SIZE, CELL_MARK_SIZE); - polyline.lineTo(width - 1 - (ringt_up_count + 1) * CELL_MARK_SIZE, 0); - GraphHelper.fill(g2d, polyline); - - g2d.setPaint(oldPaint); - return true; - } - return false; - } - - private static boolean isRightTopMarker(TemplateCellElement cell) { - return cell.getCellPageAttr() != null && (cell.getCellPageAttr().isPageAfterColumn() - || cell.getCellPageAttr().isPageBeforeColumn() - || cell.getCellPageAttr().isPageAfterRow() - || cell.getCellPageAttr().isPageBeforeRow()); - } - - private static boolean paintResultMarkWhenExsit(Graphics2D g2d, Object value, int width, int ringt_up_count) { - //右上角标记是否自定义显示 - if (value instanceof DSColumn && ((DSColumn) value).getResult() != null) { - if (!ComparatorUtils.equals(((DSColumn) value).getResult(), "$$$")) { - Paint oldPaint = g2d.getPaint(); - - g2d.setPaint(CELL_RESULT_MARK_COLOR); - GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); - polyline.moveTo(width - ringt_up_count * CELL_MARK_SIZE - 1, 0); - polyline.lineTo(width - ringt_up_count * CELL_MARK_SIZE - 1, CELL_MARK_SIZE); - polyline.lineTo(width - (ringt_up_count + 1) * CELL_MARK_SIZE - 1, 0); - GraphHelper.fill(g2d, polyline); - - g2d.setPaint(oldPaint); - return true; - } - } - - return false; - } - - private static void paintWidgetMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell, int width, int height) { - // 右下角:是否填报, 设置为4时,三角太小了,不知何故,设置为6 - if (cell.getWidget() != null) { - Widget widget = cell.getWidget(); - Image img = ((ImageIcon) ReportUtils.createWidgetIcon(widget.getClass())).getImage(); - g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.67f)); - g2d.drawImage(img, width - 15, height - 15, WIDGET_WIDTH, WIDGET_HEIGHT, null); - g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); - } - } - - private static void paintExpandMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell) { - CellExpandAttr cellExpandAttr = cell.getCellExpandAttr(); - if (cellExpandAttr != null) { - if (cellExpandAttr.getDirection() == Constants.TOP_TO_BOTTOM) { - Paint oldPaint = g2d.getPaint(); - g2d.setPaint(CELL_DIRECTION_MARK_COLOR); - GraphHelper.drawLine(g2d, 2, 0, 2, 5); - GraphHelper.drawLine(g2d, 2, 5, 0, 2); - GraphHelper.drawLine(g2d, 2, 5, 4, 2); - g2d.setPaint(oldPaint); - } else if (cellExpandAttr.getDirection() == Constants.LEFT_TO_RIGHT) { - Paint oldPaint = g2d.getPaint(); - g2d.setPaint(CELL_DIRECTION_MARK_COLOR); - GraphHelper.drawLine(g2d, 0, 2, 5, 2); - GraphHelper.drawLine(g2d, 5, 2, 2, 0); - GraphHelper.drawLine(g2d, 5, 2, 2, 4); - g2d.setPaint(oldPaint); - } - } - } - - private static boolean paintDSColumnConditionmarkWhenExsit(Graphics2D g2d, Object value, int height, int left_dowm_count) { - // 左下角:数据列(DSColumn)相关:比如条件过滤 - if (value instanceof DSColumn && ((DSColumn) value).getCondition() != null) { - if (((DSColumn) value).getCondition() instanceof ListCondition && - ((ListCondition) ((DSColumn) value).getCondition()).getJoinConditionCount() == 0) { - // do nothing - } else { - Paint oldPaint = g2d.getPaint(); - - g2d.setPaint(CELL_CONDITION_FILTER_MARK_COLOR); - GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); - polyline.moveTo(0 + left_dowm_count * CELL_MARK_SIZE, height - 1); - polyline.lineTo((left_dowm_count + 1) * CELL_MARK_SIZE + 1, height - 1); - polyline.lineTo(0 + left_dowm_count * CELL_MARK_SIZE, height - 2 - CELL_MARK_SIZE); - GraphHelper.fill(g2d, polyline); - - g2d.setPaint(oldPaint); - return true; - } - } - return false; - } - - private static boolean paintDSColumnParametermarkWhenExsit(Graphics2D g2d, Object value, int height, int left_dowm_count) { - // 左下角:动态注入参数 - if (value instanceof DSColumn && ((DSColumn) value).getParameters() != null) { - if (((DSColumn) value).getParameters().length > 0) { - Paint oldPaint = g2d.getPaint(); - - g2d.setPaint(CELL_PARAMETER_FILTER_MARK_CONLR); - GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); - polyline.moveTo(0 + left_dowm_count * CELL_MARK_SIZE, height - 1); - polyline.lineTo((left_dowm_count + 1) * CELL_MARK_SIZE + 1, height - 1); - polyline.lineTo(0 + left_dowm_count * CELL_MARK_SIZE, height - 2 - CELL_MARK_SIZE); - GraphHelper.fill(g2d, polyline); - - g2d.setPaint(oldPaint); - return true; - } - } - return false; - } - - /* - * 画悬浮元素 - * - * 仅根据宽度 + 高度画 - */ - //b:此方法在grid和tohtml的时候都被调用,所以对formula会有冲突,暂时这么改,应该考虑分开的,也可以根据result来判断,但是那么写好像不妥 - public static void paintFloatElement(Graphics2D g2d, FloatElement flotEl, int width, int height, int resolution) { - Style.paintBackground(g2d, flotEl.getStyle(), width, height); - - Object value = flotEl.getValue(); - if (value instanceof BaseFormula) { - value = ((BaseFormula) value).getContent(); - } - if (value instanceof BaseChartCollection) { - value = ((BaseChartCollection) value).createResultChartPainterWithOutDealFormula(Calculator.createCalculator(), WebChartIDInfo.createEmptyDesignerInfo(), width, height); - } - //图片需要切割一下 - if (value instanceof Image) { - value = CellUtils.value2ImageWithBackground(value, resolution, flotEl.getStyle(), width, height); - } - Style.paintContent(g2d, value, flotEl.getStyle(), width, height, resolution); - - Style.paintBorder(g2d, flotEl.getStyle(), width, height); - } - - /* - * 画悬浮元素flotEl - * - * 也就是画三个东西:背景 + 内容 + 边框 - */ - public static void paintFloatElement(Graphics2D g2d, FloatElement flotEl, Rectangle paintRectangle, Rectangle clipRectangle, int resolution) { - // 画悬浮元素的背景 - Style.paintBackground(g2d, flotEl.getStyle(), paintRectangle, clipRectangle); - - Object value = flotEl.getValue(); - if (value instanceof ResultChangeWhenExport) { - value = ((ResultChangeWhenExport) value).changeThis(); - } - // 画悬浮元素的内容 - Style.paintContent(g2d, value, resolution, flotEl.getStyle(), paintRectangle, clipRectangle); - // 画悬浮元素的边框 - Style.paintBorder(g2d, flotEl.getStyle(), paintRectangle, clipRectangle); - } - - public static void paintHTMLContent(Graphics2D g2d, String value, int resolution, Style style, Rectangle paintRectangle, Rectangle clipRectangle) { - Style.paintContent(g2d, createHTMLContentBufferedImage(value, paintRectangle, 0, 0, style), resolution, style, paintRectangle, clipRectangle); - } - - public static void paintTag(Painter painter, Repository repo, int width, int height, Style style, Tag tag) { - painter.paintTag(repo, width, height, style, tag); - } - - /** - * 如果用户希望以HTML方式展示String,这个时候先value变成图片 - * - * @param value 值 - * @param paintRectangle 绘制范围 - * @param x x坐标 - * @param y y坐标 - * @param style 当前格子样式 - * @return BufferedImage 返回图片. - */ - public static BufferedImage createHTMLContentBufferedImage(String value, Rectangle paintRectangle, int x, int y, Style style) { - return Html2ImageUtils.createHTMLContentBufferedImage(value, paintRectangle, x, y, style); - } - - /** - * see BaseUtils.getLineTextList, 等于BaseUtils.getLineTextList().size() - * Denny: 为了提高速度和性能,才单独拿出来的 - * TODO: 重构 - * - * @param text 文本 - * @param style 样式 - * @param paintWidth 单元格宽度 - * @return paintWidth 单位为PT - */ - public static int getLineTextCount(String text, Style style, UNIT paintWidth) { - if (style.getRotation() != 0) { - return 1; - } - - - if (style.getTextStyle() != Style.TEXTSTYLE_WRAPTEXT) { - return dealNotWrapTextCount(text.toCharArray()); - } else {// 自动换行 - return dealWrapTextCount(text, style, paintWidth); - } - } - - private static int dealNotWrapTextCount(char[] text_chars) { - boolean remain_chars = false; - int count = 0; - for (int t = 0; t < text_chars.length; t++) { - if (text_chars[t] == '\\') {// 判断是否是 "\n" - if (t + 1 < text_chars.length && text_chars[t + 1] == 'n') { - // 是"\n"字符串,但不是换行符. - t++; - count++; - if (remain_chars) { - remain_chars = false; - } - } else { - if (!remain_chars) { - remain_chars = true; - } - } - } else if (text_chars[t] == '\n' || (text_chars[t] == '\r' && t + 1 < text_chars.length - 1 && text_chars[t + 1] != '\n')) { - count++; - if (remain_chars) { - remain_chars = false; - } - } else { - if (!remain_chars) { - remain_chars = true; - } - } - } - - // 最后一个 - if (remain_chars) { - count++; - } - - return count; - } - - // 自动换行 - //neil:style里面, 默认值padding right = 2时, 默认不生效, 这边算行高时也不要计算入内 - //临时处理, 去掉左边框线, 因为浏览器计算时需要考虑左边框线宽度, 但这边还是存在问题的 - //同样需要考虑的是导出和web端展示, padding计算方式也不一致. - private static int dealWrapTextCount(String text, Style style, UNIT unitWidth) { - AutoChangeLineAndDrawProcess process = AutoChangeLineAndDrawManager.getProcess(); - if (process != null) { - return process.getAutoChangeLineCount(text, new ObjectHolder(style), unitWidth); - } - int count = 0; - char[] text_chars = text.toCharArray(); - FontMetrics fontMetrics = getFontMetrics(style); - double paintWidth = unitWidth.toPixD(Constants.FR_PAINT_RESOLUTION); - double width = paintWidth - style.getPaddingLeft() - (style.getPaddingRight() == Style.DEFAULT_PADDING ? 0 : style.getPaddingRight()) - style.getBorderLeftWidth(); - boolean remain_lineText = false; - int lineTextWidth = 0; - int wordWidth = 0; - for (int t = 0, len = text_chars.length; t < len; t++) { - if (t != 0 && BaseUtils.isNumOrLetter(text_chars[t]) && BaseUtils.isNumOrLetter(text_chars[t - 1])) { - if (wordWidth + fontMetrics.charWidth(text_chars[t]) > width) { - if (lineTextWidth > 0) { - count++; - remain_lineText = false; - lineTextWidth = 0; - } - count++; - wordWidth = 0; - } - wordWidth += fontMetrics.charWidth(text_chars[t]); - } else if (isSwitchLine(text_chars, t) || isLN(text_chars, t)) {// 判断是否是 "\n" - if (isLN(text_chars, t)) { - t++;// 忽略'n'字符.// 是"\n"字符串,但不是换行符,依然需要换行. - } - if (lineTextWidth + wordWidth > width && remain_lineText) { - count += 2; - } else { - count++; - } - remain_lineText = false; - lineTextWidth = 0; - wordWidth = 0; - } else { - if (text_chars[t] == '\\' && t + 1 < text_chars.length && text_chars[t + 1] == '\\') {// 判断是否是转义字符'\' - t++;// _denny: 增加了转义字符'\\'用来表示\,使"\n"可以输入 - } - if (lineTextWidth + wordWidth > width && remain_lineText) { - count++; - lineTextWidth = isPunctuationAtLineHead(t, text_chars) ? dealLineWidthWithPunctuation(t, text_chars, fontMetrics) : 0; - } - remain_lineText = true; - lineTextWidth += wordWidth; - wordWidth = fontMetrics.charWidth(text_chars[t]); - } - } - if (lineTextWidth + wordWidth > width && remain_lineText) { - count += 2; - } else { - count++; - } - return count; - } - - /** - * 标点符号是否在换行后的行首 - */ - private static boolean isPunctuationAtLineHead(int t, char[] text_chars) { - if (t > 1 && BaseUtils.isPunctuation(text_chars[t - 1])) { - return true; - } - return false; - } - - /** - * 防止有连续多个标点符号,要找一个非标点符号字符 - * - * @date 2014-4-17 - */ - private static int dealLineWidthWithPunctuation(int t, char[] text_chars, FontMetrics fontMetrics) { - if (t < 2) { - return 0; - } - int lineWidth = 0; - for (int index = t - 2; index >= 0; index--) { - lineWidth += fontMetrics.charWidth(text_chars[index]); - if (!BaseUtils.isPunctuation(text_chars[index])) { - break; - } - } - return lineWidth; - } - - private static boolean isSwitchLine(char[] text_chars, int t) { - return text_chars[t] == '\n' || (text_chars[t] == '\r' && t + 1 < text_chars.length - 1 && text_chars[t + 1] != '\n'); - } - - private static boolean isLN(char[] text_chars, int t) { - return text_chars[t] == '\\' && t + 1 < text_chars.length && text_chars[t + 1] == 'n'; - } - - /** - * Gets the preferred width. - */ - public static UNIT getPreferredWidth(CellElement cell, UNIT height) { - if (cell == null) { - return UNIT.ZERO; - } - - Object value = cell.getShowValue(); - // 只接受Text,Number,和SeparatorPainter - // got the text - if (value instanceof BaseFormula) { - if (((BaseFormula) value).getResult() != null) { - value = ((BaseFormula) value).getResult(); - } else { - value = StringUtils.EMPTY; - } - } - Style style = cell.getStyle(); - if (style == null) { - style = Style.DEFAULT_STYLE; - } - CellGUIAttr cg = cell.getCellGUIAttr() == null ? new CellGUIAttr() : cell.getCellGUIAttr(); - value = Utils.resolveOtherValue(value, cg.isShowAsImage(), PresentationType.EXPORT); - String text = Style.valueToText(value, style.getFormat()); - - FontMetrics cellFM = getFontMetrics(style); - //bug 12151 有边框线的单元格 自动调整列宽 会多一行 - UNIT padding = new PT(style.getPaddingLeft() + style.getPaddingRight()); - - if (cg.isShowAsHTML()) { - return Html2ImageUtils.getHtmlWidth(text, height, style); - } - - return FU.valueOfPix(cellFM.stringWidth(text) + UNIT_SIZE, Constants.FR_PAINT_RESOLUTION).add(padding); - } - - private static FontMetrics getFontMetrics(Style style) { - Font font = style.getFRFont().applyResolutionNP(Constants.FR_PAINT_RESOLUTION); - FontProcessor processor = ExtraClassManager.getInstance().getSingle(FontProcessor.MARK_STRING); - if (processor != null) { - font = processor.readExtraFont(font); - } - return GraphHelper.getFontMetrics(font); - } - - /** - * Preferred height. (Got the shrink preferred height of CellElement). - * 单位格的预计算高度 - * - * @param cellElement 单元格内容 - * @param paintWidth 画的宽度 - * @return UNIT 单位 - */ - public static UNIT analyzeCellElementPreferredHeight(CellElement cellElement, UNIT paintWidth) { - // 计算高度用显示值 - Object value = cellElement.getShowValue(); - // 只接受Text,Number,和SeparatorPainter - Style style = cellElement.getStyle(); - // got the text - if (value instanceof BaseFormula) { - if (((BaseFormula) value).getResult() != null) { - value = ((BaseFormula) value).getResult(); - } else { - value = StringUtils.EMPTY; - } - } - CellGUIAttr cg = cellElement.getCellGUIAttr() == null ? new CellGUIAttr() : cellElement.getCellGUIAttr(); - if (!(value instanceof String) && !(value instanceof Integer)) { - value = DataUtils.resolveOtherValue(value, cg.isShowAsImage(), cg.isShowAsDownload(), null, true); - } - String text = Style.valueToText(value, style.getFormat()); - - if (cg.isShowAsHTML()) { - return Html2ImageUtils.getHtmlHeight(text, paintWidth, style); - } - - return PaintUtils.analyzeCellElementPreferredHeight(text, style, paintWidth, cg.isShowAsHTML()); - } - - /** - * 单位格的预计算高度 - * 单位PT - * - * @param text 文本 - * @param style 格式 - * @param paintWidth 画的宽度 - * @param isShowAsHtml 是否以html展示 - * @return 返回 单位 - */ - private static UNIT analyzeCellElementPreferredHeight(String text, Style style, UNIT paintWidth, boolean isShowAsHtml) { - if (style == null) { - //peter:获取默认的Style. - style = Style.DEFAULT_STYLE; - } - - // got the text - if (text == null || text.length() <= 0) { - return PT.valueOf(0); - } - - // 变成Line Text List. - if (style.getRotation() != 0) { // more easy to paint. - // attribute map. - return PT.valueOf((float) GraphHelper.stringDimensionWithRotation(text, style.getFRFont(), -style.getRotation(), - CoreConstants.DEFAULT_FRC).getHeight()); - } - // 先获得FontMetics. - int lineCount = getLineTextCount(text, style, paintWidth); - AutoChangeLineAndDrawProcess process = AutoChangeLineAndDrawManager.getProcess(); - if (process != null) { - //算了这两个接口分开做 - return process.getLinedTextHeight(lineCount, new ObjectHolder(style)); - } - - // carl:和paint那边一致,添上段前段后和行间距 - PT lineSpacing = PT.valueOf(style.getSpacingAfter() + style.getSpacingBefore() + style.getLineSpacing() * lineCount); - FontMetrics fontMetrics = getFontMetrics(style); - int textHeight = fontMetrics.getHeight(); - FU allTextHeight = FU.valueOfPix(textHeight * lineCount, Constants.FR_PAINT_RESOLUTION); - return lineSpacing.add(allTextHeight);// 需要给底部添加Leading. - } - - /** - * 截取文字,只考虑了垂直方向,水平方向没意义且难度大. - * - * @param value 画的值 - * @param style 字体样式格式. - * @param blockArea 冻结的范围 - * @param resolution 分辨率 - * @return 返回的字符串 - */ - public static String clipBlockValue(Object value, Style style, Rectangle primitiveArea, Rectangle blockArea, int resolution, boolean isShowAsHTML) { - if (value == null) { - return null; - } - if (value instanceof BaseFormula) { - value = ((BaseFormula) value).getResult(); - } - if (blockArea.y >= primitiveArea.height || blockArea.y + blockArea.height <= 0) { - return null; - } - //截取位置,相对于clipArea - int startY = blockArea.y > 0 ? blockArea.y : 0; - int endY = blockArea.y + blockArea.height < primitiveArea.height ? blockArea.y + blockArea.height : primitiveArea.height; - if (blockArea.x >= primitiveArea.width || blockArea.x + blockArea.width <= 0) { - return null; - } - if (isShowAsHTML) { - return Html2ImageUtils.clipHtmlContent(value, style, primitiveArea, resolution, startY, endY); - } - List lineList = BaseUtils.getLineTextList((String) value, style, style.getFRFont().applyResolutionNP(resolution), primitiveArea.width, resolution); - if (lineList.isEmpty()) { - return null; - } - double spacingBefore = PT.pt2pix(style.getSpacingBefore(), resolution); - double spacingAfter = PT.pt2pix(style.getSpacingAfter(), resolution); - double lineSpacing = PT.pt2pix(style.getLineSpacing(), resolution); - double lineHeight = lineSpacing + GraphHelper.getFontMetrics(style.getFRFont().applyResolutionNP(resolution)).getHeight(); - int textAllHeight = (int) (lineHeight * lineList.size() + spacingBefore + spacingAfter); - //第一行文字距区域高度 - int textStartY = (int) spacingBefore; - - if (style.getVerticalAlignment() == Constants.BOTTOM) { - textStartY += (primitiveArea.height - textAllHeight); - } - if (endY <= textStartY || startY >= textStartY + lineHeight * lineList.size()) { - return null; - } - int lineStart = getLineStart(lineList, lineHeight, textStartY, startY);//截取区域起始行 - int lineEnd = getLineEnd(lineList, lineHeight, endY, textStartY);//截取区域结束行 - String text = ""; - for (; lineStart <= lineEnd; lineStart++) { - text += lineList.get(lineStart); - } - return text; - } - - private static int getLineStart(List lineList, double lineHeight, int textStartY, int startY) { - int lineStart = 0; - for (int i = 0; i < lineList.size(); i++) { - if (textStartY + lineHeight * (i) <= startY && textStartY + lineHeight * (i + 1) > startY) {//压线 - if (startY - textStartY - lineHeight * (i) > lineHeight / 2) { - lineStart = i + 1; - } else { - lineStart = i; - } - } - } - return lineStart; - } - - private static int getLineEnd(List lineList, double lineHeight, int endY, int textStartY) { - int lineEnd = lineList.size() - 1; - for (int i = 0; i < lineList.size(); i++) { - if (textStartY + lineHeight * (i) < endY && textStartY + lineHeight * (i + 1) >= endY) {//压线 - //neil:仿宋,12号字, 行间距8为例, 转为px的行间距大小为10.666, 这边算出的应该有31.98行, 因此要进位 - if (endY - textStartY - lineHeight * (i) >= lineHeight / 2) { - lineEnd = i; - } else { - lineEnd = i - 1; - } - } - } - return lineEnd; - } - - /** - * paintBarcode - */ - public static void paintBarcode(Graphics2D g2d, int width, int height, String text, Style style, BarcodeAttr barcodeAttr) { - BarcodeImpl barcodeImpl; - try { - barcodeImpl = BarCodeUtils.getBarcodeImpl(barcodeAttr, text); - } catch (BarcodeException exp) { - try { - //设置默认值. - barcodeImpl = BarCodeUtils.getBarcodeImpl(new BarcodeAttr(), null); - } catch (BarcodeException e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - return; - } - } - - //字体 - if (style.getFRFont() != null) { - barcodeImpl.setFont(style.getFRFont()); - barcodeImpl.setForeground(style.getFRFont().getForeground()); - } - //背景 - Background background = style.getBackground(); - if (background != null && background instanceof ColorBackground) { - barcodeImpl.setBackground(((ColorBackground) background).getColor()); - } - - //根据宽度和高度来确定起始点 - int pointX = (width - barcodeImpl.getWidth()) / 2; - int pointY = (height - barcodeImpl.getHeight()) / 2; - - barcodeImpl.draw(g2d, pointX, pointY); - } - - /** - * create font attribute map, 创建属性map - * - * @param font 字体 - * @return map 返回字体创建的Map - */ - public static Map createFontAttributeMap(Font font) { - Map returnFontAttributeMap = (Map) fontAttributeMapCache.get(font); - if (returnFontAttributeMap == null) {// create - // returnFontAttributeMap. - returnFontAttributeMap = font.getAttributes(); - fontAttributeMapCache.put(font, returnFontAttributeMap); - } - - if (font instanceof FRFont) { - FRFont frFont = (FRFont) font; - - // Strikethrough - if (frFont.isStrikethrough()) { - returnFontAttributeMap.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON); - } - } - - return returnFontAttributeMap; - } - -} diff --git a/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java b/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java index f763fbf3a..47512348f 100644 --- a/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java +++ b/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java @@ -1,13 +1,9 @@ package com.fr.design.fit.common; - import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.file.MutilTempalteTabPane; -import com.fr.design.fit.DesignerUIModeConfig; -import com.fr.design.fit.JFormType; import com.fr.design.fit.NewJForm; import com.fr.design.mainframe.DesignerContext; -import com.fr.design.mainframe.JForm; import com.fr.design.mainframe.JTemplate; import com.fr.event.Event; import com.fr.event.Listener; @@ -23,31 +19,20 @@ import java.util.List; * @create: 2020/09/03 14:19 */ public class TemplateTool { - //和转换有关的所有代码都在这个监听器中 - //在判断新老模式时,统一使用FormUIModeConfig.getInstance().newUIMode()进行判断 - private static Listener switchListener = new Listener() { + private static final Listener switchListener = new Listener() { @Override public void on(Event event, JTemplate jTemplate) { - if (!(jTemplate instanceof JForm)) { - JFormType.OLD_TYPE.switchUIMode(); - return; - } - JFormType currentType = JFormType.OLD_TYPE; - if (AdaptiveSwitchUtil.isSwitchJFromIng()) { - currentType = DesignerUIModeConfig.getInstance().newUIMode() ? JFormType.NEW_TYPE : JFormType.OLD_TYPE; - } else if (isNewJForm(jTemplate)) { - currentType = JFormType.NEW_TYPE; - } - //UI转换 - currentType.switchUIMode(); - //标志位转换 - currentType.updateJFromTemplateType(jTemplate); - //预览方式转换 - currentType.updatePreviewType(jTemplate); + jTemplate.setDesignerUIMode(); } }; - private static boolean isNewJForm(JTemplate jTemplate) { + + public static Listener getSwitchListener() { + return switchListener; + } + + + public static boolean isNewJForm(JTemplate jTemplate) { if (jTemplate instanceof NewJForm) { NewJForm newJForm = (NewJForm) jTemplate; if (LightTool.containNewFormFlag(newJForm.getTarget()) || newJForm.getTarget().getTemplateID() == null) { @@ -57,8 +42,8 @@ public class TemplateTool { return false; } - public static Listener getSwitchListener() { - return switchListener; + public static boolean isCurrentEditingNewJForm(){ + return isNewJForm(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate()); } /** @@ -69,8 +54,7 @@ public class TemplateTool { * @date: 2020/9/6 14:17 */ public static JTemplate getCurrentEditingTemplate() { - JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - return jTemplate; + return HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); } /** @@ -159,4 +143,6 @@ public class TemplateTool { } + + } diff --git a/designer-form/src/main/java/com/fr/design/fit/toolbar/SwitchAction.java b/designer-form/src/main/java/com/fr/design/fit/toolbar/SwitchAction.java index e14d39a68..bf490a720 100644 --- a/designer-form/src/main/java/com/fr/design/fit/toolbar/SwitchAction.java +++ b/designer-form/src/main/java/com/fr/design/fit/toolbar/SwitchAction.java @@ -3,7 +3,6 @@ package com.fr.design.fit.toolbar; import com.fr.design.actions.UpdateAction; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.file.TemplateTreePane; -import com.fr.design.fit.DesignerUIModeConfig; import com.fr.design.fit.NewJForm; import com.fr.design.fit.common.AdaptiveSwitchUtil; import com.fr.design.fit.common.TemplateTool; @@ -11,6 +10,7 @@ import com.fr.design.gui.ibutton.UIButton; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.BaseJForm; import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JForm; import com.fr.design.mainframe.JTemplate; import com.fr.design.menu.MenuKeySet; import com.fr.file.FILE; @@ -64,11 +64,11 @@ public class SwitchAction extends UpdateAction { } }; - public SwitchAction() { - initMenuStyle(); + public SwitchAction(JForm jForm) { + initMenuStyle(jForm); } - private void initMenuStyle() { + private void initMenuStyle(JForm jForm) { this.setMenuKeySet(SWITCH_ATTR); this.setName(getMenuKeySet().getMenuKeySetName()); this.setMnemonic(getMenuKeySet().getMnemonic()); @@ -80,7 +80,7 @@ public class SwitchAction extends UpdateAction { Font oldFont = switchBtn.getFont(); switchBtn.setFont(new Font(oldFont.getName(),oldFont.getStyle(),12)); switchBtn.setForeground(new Color(0x33, 0x33, 0x34)); - freshSwitchButton(); + freshSwitchButton(jForm); } @Override @@ -92,11 +92,7 @@ public class SwitchAction extends UpdateAction { if (confirmSwitchDialog() && backUpOldModeJTemplate()) { AdaptiveSwitchUtil.setSwitchJFromIng(1); showLoadingJPanel(); - if (DesignerUIModeConfig.getInstance().newUIMode()) { - AdaptiveSwitchUtil.switch2OldUI(); - } else { - AdaptiveSwitchUtil.switch2NewUI(); - } + AdaptiveSwitchUtil.switchReload(); } } @@ -175,7 +171,7 @@ public class SwitchAction extends UpdateAction { */ private boolean backUpOldModeJTemplate() { JTemplate jTemplate = TemplateTool.getCurrentEditingTemplate(); - if (jTemplate != null && !DesignerUIModeConfig.getInstance().newUIMode()) { + if (jTemplate != null && !TemplateTool.isNewJForm(jTemplate)) { FILE editingFILE = jTemplate.getEditingFILE(); if (editingFILE != null && editingFILE.exists()) { try { @@ -237,7 +233,7 @@ public class SwitchAction extends UpdateAction { * @date: 2020/9/18 11:20 */ private boolean confirmSwitchDialog() { - Object message = DesignerUIModeConfig.getInstance().newUIMode() ? Toolkit.i18nText("Fine-Designer_Fit_Confirm_New_Old_Switch") : Toolkit.i18nText("Fine-Designer_Fit_Confirm_Old_New_Switch"); + Object message = TemplateTool.isCurrentEditingNewJForm() ? Toolkit.i18nText("Fine-Designer_Fit_Confirm_New_Old_Switch") : Toolkit.i18nText("Fine-Designer_Fit_Confirm_Old_New_Switch"); int returnVal = FineJOptionPane.showConfirmDialog( DesignerContext.getDesignerFrame(), message, @@ -269,8 +265,8 @@ public class SwitchAction extends UpdateAction { * @Author: Henry.Wang * @date: 2020/8/31 16:39 */ - public UIButton freshSwitchButton() { - if (DesignerUIModeConfig.getInstance().newUIMode()) { + public UIButton freshSwitchButton(JForm jForm) { + if (TemplateTool.isNewJForm(jForm)) { switchBtn.setToolTipText(Toolkit.i18nText("Fine-Designer_Fit_Switch_To_Old_UI")); switchBtn.setText(Toolkit.i18nText("Fine-Designer_Fit_Switch_To_Old_Version")); } else { @@ -281,7 +277,7 @@ public class SwitchAction extends UpdateAction { } public UIButton getToolBarButton() { - return freshSwitchButton(); + return switchBtn; } } 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 845c270b7..adc59581a 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 @@ -43,7 +43,6 @@ import com.fr.design.designer.properties.FormWidgetAuthorityEditPane; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.event.DesignerOpenedListener; import com.fr.design.file.HistoryTemplateListPane; -import com.fr.design.fit.DesignerUIModeConfig; import com.fr.design.form.util.XCreatorConstants; import com.fr.design.fun.RightSelectionHandlerProvider; import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; 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 d61cd5902..8d2748eb3 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 @@ -1235,4 +1235,8 @@ public class JForm extends JTemplate implements BaseJForm { public RootDesignDefinePane(XCreator xCreator) { super(xCreator); - newForm = TemplateTool.getCurrentEditingNewJForm() != null && DesignerUIModeConfig.getInstance().newUIMode(); + newForm = TemplateTool.getCurrentEditingNewJForm() != null && DesignerUIModeConfig.getInstance().simulateWebUIMode(); this.root = (XWParameterLayout) xCreator; initComponent(); } 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 9507248df..3eb947488 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,7 +5,7 @@ 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.common.TemplateTool; import com.fr.design.fit.attrpane.PcFitExpandablePane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.style.FollowingThemePane; @@ -76,7 +76,7 @@ public class ElementEditorDefinePane extends WTitleLayoutDefinePane list = new ArrayList(); @@ -102,7 +102,7 @@ public class ElementEditorDefinePane extends WTitleLayoutDefinePane selectedColumns[selectedColumns.length - 1]) { - resetGridSelectionBySelect(selectedCellPoint.getColumn(), ePane); - } - } - - - protected int doChooseFrom() { - return CellSelection.CHOOSE_COLUMN; - } - - @Override - protected Rectangle resetSelectedBoundsByShift(Rectangle editRectangle, ColumnRow selectedCellPoint, ElementCasePane reportPane) { - int tempOldSelectedCellX = editRectangle.x;// editRectangle.x; - - // adjust them to got the correct selected bounds. - if (selectedCellPoint.getColumn() >= editRectangle.x) { - selectedCellPoint = ColumnRow.valueOf(selectedCellPoint.getColumn() + 1, selectedCellPoint.getRow()); - } else { - tempOldSelectedCellX++; - } - - int lastRow = GridUtils.getAdjustLastColumnRowOfReportPane(reportPane).getRow(); - return new Rectangle(Math.min(tempOldSelectedCellX, selectedCellPoint.getColumn()), 0, Math.max(editRectangle.width, Math.abs(tempOldSelectedCellX - - selectedCellPoint.getColumn())), lastRow); - } - - @Override - protected int[] getGridSelectionIndices(CellSelection cs) { - return cs.getSelectedColumns(); - } - - @Override - protected int getScrollValue(ElementCasePane casePane) { - return casePane.getGrid().getHorizontalValue(); - } - - @Override - protected int getScrollExtent(ElementCasePane casePane) { - return casePane.getGrid().getHorizontalExtent(); - } - - @Override - protected int getBeginValue(ElementCasePane casePane) { - return casePane.getGrid().getHorizontalBeginValue(); - } - - @Override - protected int getColumnOrRowByGridHeader(ColumnRow selectedCellPoint) { - return selectedCellPoint.getColumn(); - } - - - /** - * Checks whether is on zero separator line. - */ - @Override - protected boolean isOnSeparatorLineIncludeZero(MouseEvent evt, double tmpWidth2, double tmpIncreaseWidth) { - return tmpIncreaseWidth <= 1 && (evt.getX() >= tmpWidth2 + 2 && (evt.getX() <= tmpWidth2 + SEPARATOR_GAP)); - } - - @Override - protected boolean between(MouseEvent evt, double from, double to) { - return evt.getX() > from && evt.getX() <= to; - } - - /** - * Checks whether is on normal separator line. - */ - @Override - protected boolean isOnNormalSeparatorLine(MouseEvent evt, double tmpWidth2) { - return (evt.getX() >= tmpWidth2 - 2) && (evt.getX() <= tmpWidth2 + 2); - } - - @Override - protected int evtOffset(MouseEvent evt, int offset) { - return evt.getX() - offset; - } - - @Override - protected DynamicUnitList getSizeList(ElementCase elementCase) { - return ReportHelper.getColumnWidthList(elementCase); - } - - @Override - protected String methodName() { - return "setColumnWidth"; - } - - @Override - protected String getSelectedHeaderTooltip(int selectedColumnCount) { - return selectedColumnCount + "C"; - } - - @Override - protected Point getTipLocationByMouseEvent(MouseEvent evt, GridHeader gHeader, Dimension tipPreferredSize) { - Point convertPoint = new Point(evt.getX(), 0); - SwingUtilities.convertPointToScreen(convertPoint, gHeader); - - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - convertPoint.x = Math.max(0, Math.min(convertPoint.x - tipPreferredSize.width / 2, screenSize.width - tipPreferredSize.width)); - convertPoint.y = convertPoint.y - tipPreferredSize.height - 2; - - return convertPoint; - } - - @Override - protected void resetGridSelectionBySelect(int column, ElementCasePane ePane) { - int lastRow = GridUtils.getAdjustLastColumnRowOfReportPane(ePane).getRow(); - CellSelection cellSelection = new CellSelection(column, 0, 1, lastRow); - cellSelection.setSelectedType(CellSelection.CHOOSE_COLUMN); - ePane.setSelection(cellSelection); - } - - @Override - protected String nameOfMoveCursorGIF() { - return "cursor_hmove"; - } - - @Override - protected String nameOfSelectCursorGIF() { - return "cursor_hselect"; - } - - @Override - protected String nameOfSplitCursorGIF() { - return "cursor_hsplit"; - } - - @Override - protected UIPopupMenu createPopupMenu(ElementCasePane reportPane, - MouseEvent evt, int columnIndex) { - return ElementCasePaneUtil.createColumnPopupMenu(reportPane, evt, columnIndex); - } - - @Override - protected void resetGridSelectionByDrag(CellSelection gridSelection, ElementCasePane reportPane, - int startMultiSelectIndex, int endMultiSelectIndex) { - int lastRow = GridUtils.getAdjustLastColumnRowOfReportPane(reportPane).getRow(); - gridSelection.setLastRectangleBounds(Math.min(endMultiSelectIndex, startMultiSelectIndex), 0, Math.abs(startMultiSelectIndex - endMultiSelectIndex) + 1, lastRow); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - int resolution = DesignerUIModeConfig.getInstance().getScreenResolution(); - int dragIndex = getDragIndex(e); - if (Math.abs(e.getX() - getLimit()) < FUZZY_EDGE && dragIndex >= 0) { - UNIT oldValue = this.getEditingElementCase().getColumnWidth(dragIndex); - this.getEditingElementCase().setColumnWidth(dragIndex, FU.valueOfPix(oldValue.toPixI(resolution) + getLimit() - e.getX(), resolution)); - } - this.getElementCasePane().repaint(); - } - -} diff --git a/designer-realize/src/main/java/com/fr/design/fit/grid/GridLimitRowMouseHandler.java b/designer-realize/src/main/java/com/fr/design/fit/grid/GridLimitRowMouseHandler.java deleted file mode 100644 index ac4a70eab..000000000 --- a/designer-realize/src/main/java/com/fr/design/fit/grid/GridLimitRowMouseHandler.java +++ /dev/null @@ -1,190 +0,0 @@ -package com.fr.design.fit.grid; - -import com.fr.base.DynamicUnitList; -import com.fr.design.fit.DesignerUIModeConfig; -import com.fr.design.gui.imenu.UIPopupMenu; -import com.fr.design.mainframe.ElementCasePane; -import com.fr.grid.GridHeader; -import com.fr.grid.GridRow; -import com.fr.grid.GridUtils; -import com.fr.grid.selection.CellSelection; -import com.fr.grid.selection.Selection; -import com.fr.report.ReportHelper; -import com.fr.report.elementcase.ElementCase; -import com.fr.stable.ColumnRow; -import com.fr.stable.unit.FU; -import com.fr.stable.unit.UNIT; - -import javax.swing.SwingUtilities; -import java.awt.Dimension; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.event.MouseEvent; - -/** - * peter:处理对GridRow的Mouse事件. - */ -public class GridLimitRowMouseHandler extends GridHeaderWithBoundMouseHandler { - - public GridLimitRowMouseHandler(GridRow gridRow, int limit) { - super(gridRow, limit); - } - - @Override - protected void resetSelectionByRightButton(ColumnRow selectedCellPoint, Selection cs, ElementCasePane ePane) { - int[] selectedRows = cs.getSelectedRows(); - if (selectedRows.length == 0 - || selectedCellPoint.getRow() < selectedRows[0] - || selectedCellPoint.getRow() > selectedRows[selectedRows.length - 1]) { - resetGridSelectionBySelect(selectedCellPoint.getRow(), ePane); - } - } - - - protected int doChooseFrom() { - return CellSelection.CHOOSE_ROW; - } - - @Override - protected int getScrollValue(ElementCasePane casePane) { - return casePane.getGrid().getVerticalValue(); - } - - @Override - protected int getScrollExtent(ElementCasePane casePane) { - return casePane.getGrid().getVerticalExtent(); - } - - @Override - protected int getBeginValue(ElementCasePane casePane) { - return casePane.getGrid().getVerticalBeginValue(); - } - - @Override - protected Rectangle resetSelectedBoundsByShift(Rectangle editRectangle, ColumnRow selectedCellPoint, ElementCasePane reportPane) { - int tempOldSelectedCellY = editRectangle.y;// editRectangle.x; - - // ajust them to got the correct selected bounds. - if (selectedCellPoint.getRow() >= editRectangle.y) { - selectedCellPoint = ColumnRow.valueOf(selectedCellPoint.getColumn(), selectedCellPoint.getRow() + 1); - } else { - tempOldSelectedCellY++; - } - - int lastColumn = GridUtils.getAdjustLastColumnRowOfReportPane(reportPane).getColumn(); - return new Rectangle(0, Math.min(tempOldSelectedCellY, selectedCellPoint.getRow()), - lastColumn, Math.max(editRectangle.height, Math.abs(tempOldSelectedCellY - selectedCellPoint.getRow()))); - } - - @Override - protected int[] getGridSelectionIndices(CellSelection cs) { - return cs.getSelectedRows(); - } - - @Override - protected int getColumnOrRowByGridHeader(ColumnRow selectedCellPoint) { - return selectedCellPoint.getRow(); - } - - - @Override - protected void resetGridSelectionBySelect(int row, ElementCasePane ePane) { - int lastColumn = GridUtils.getAdjustLastColumnRowOfReportPane(ePane).getColumn(); - CellSelection cellSelection = new CellSelection(0, row, lastColumn, 1); - cellSelection.setSelectedType(CellSelection.CHOOSE_ROW); - ePane.setSelection(cellSelection); - } - - /** - * Checks whether is on zero separator line. - */ - @Override - protected boolean isOnSeparatorLineIncludeZero(MouseEvent evt, double tmpHeight2, double tmpIncreaseHeight) { - return tmpIncreaseHeight <= 1 && (evt.getY() >= tmpHeight2 + 2 && evt.getY() <= tmpHeight2 + SEPARATOR_GAP); - } - - @Override - protected boolean between(MouseEvent evt, double from, double to) { - return evt.getY() > from && evt.getY() <= to; - } - - @Override - protected DynamicUnitList getSizeList(ElementCase elementCase) { - return ReportHelper.getRowHeightList(elementCase); - } - - @Override - protected String methodName() { - return "setRowHeight"; - } - - /** - * Checks whether is on normal separator line. - */ - @Override - protected boolean isOnNormalSeparatorLine(MouseEvent evt, double tmpHeight2) { - return (evt.getY() >= tmpHeight2 - 2) && (evt.getY() <= tmpHeight2 + 2); - } - - @Override - protected int evtOffset(MouseEvent evt, int offset) { - return evt.getY() - offset; - } - - @Override - protected String getSelectedHeaderTooltip(int rowSelectedCount) { - return rowSelectedCount + "R"; - } - - @Override - protected Point getTipLocationByMouseEvent(MouseEvent evt, GridHeader gHeader, Dimension tipPreferredSize) { - Point convertPoint = new Point(0, evt.getY()); - SwingUtilities.convertPointToScreen(convertPoint, gHeader); - - convertPoint.x = convertPoint.x + gHeader.getSize().width + 2; - convertPoint.y = convertPoint.y - tipPreferredSize.height / 2; - - return convertPoint; - } - - @Override - protected String nameOfMoveCursorGIF() { - return "cursor_vmove"; - } - - @Override - protected String nameOfSelectCursorGIF() { - return "cursor_vselect"; - } - - @Override - protected String nameOfSplitCursorGIF() { - return "cursor_vsplit"; - } - - @Override - protected UIPopupMenu createPopupMenu(ElementCasePane reportPane, - MouseEvent evt, int rowIndex) { - return ElementCasePaneUtil.createRowPopupMenu(reportPane, evt, rowIndex); - } - - @Override - protected void resetGridSelectionByDrag(CellSelection gridSelection, ElementCasePane reportPane, - int startMultiSelectIndex, int endMultiSelectIndex) { - int lastColumn = GridUtils.getAdjustLastColumnRowOfReportPane(reportPane).getColumn(); - gridSelection.setLastRectangleBounds(0, Math.min(endMultiSelectIndex, startMultiSelectIndex), lastColumn, Math.abs(startMultiSelectIndex - endMultiSelectIndex) + 1); - - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - int resolution = DesignerUIModeConfig.getInstance().getScreenResolution(); - int dragIndex = getDragIndex(e); - if (Math.abs(e.getY() - getLimit()) < FUZZY_EDGE && dragIndex >= 0) { - UNIT oldValue = this.getEditingElementCase().getRowHeight(dragIndex); - this.getEditingElementCase().setRowHeight(dragIndex, FU.valueOfPix(oldValue.toPixI(resolution) + getLimit() - e.getY(), resolution)); - } - this.getElementCasePane().repaint(); - } -} diff --git a/designer-realize/src/main/java/com/fr/design/fit/grid/NewFormDesignerGridUI.java b/designer-realize/src/main/java/com/fr/design/fit/grid/NewFormDesignerGridUI.java deleted file mode 100644 index 9a2601aee..000000000 --- a/designer-realize/src/main/java/com/fr/design/fit/grid/NewFormDesignerGridUI.java +++ /dev/null @@ -1,201 +0,0 @@ -package com.fr.design.fit.grid; - -import com.fr.design.designer.creator.XElementCase; -import com.fr.design.fit.AdaptiveCellElementPainter; -import com.fr.design.fit.DesignerUIModeConfig; -import com.fr.design.fit.common.FormDesignerUtil; -import com.fr.design.mainframe.ElementCasePane; -import com.fr.design.mainframe.FormDesigner; -import com.fr.grid.CellElementPainter; -import com.fr.grid.Grid; -import com.fr.grid.GridColumn; -import com.fr.grid.GridRow; -import com.fr.grid.GridUI; -import com.fr.report.elementcase.TemplateElementCase; -import com.fr.report.worksheet.FormElementCase; -import com.fr.stable.Constants; -import com.fr.stable.GraphDrawHelper; - -import javax.swing.JComponent; -import java.awt.Color; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Insets; -import java.awt.Rectangle; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.awt.event.MouseWheelListener; - - -/** - * Created by kerry on 2020-04-14 - */ -public class NewFormDesignerGridUI extends GridUI { - private GridLimitColumnMouseHandler gridColumnMouseHandler; - private GridLimitRowMouseHandler gridRowMouseHandler; - private AdaptiveGridListener adaptiveGridListener; - private FormDesigner designer; - - public NewFormDesignerGridUI(FormDesigner designer, int resolution) { - super(resolution); - this.designer = designer; - this.setCellElementPainter(new AdaptiveCellElementPainter()); - } - - public void setCellElementPainter(CellElementPainter elementPainter) { - this.painter = elementPainter; - } - - public void paint(Graphics g, JComponent c) { - Graphics2D g2d = (Graphics2D) g; - Grid grid = (Grid) c; - // 取得ElementCasePane.ElementCase - ElementCasePane elementCasePane = grid.getElementCasePane(); - final TemplateElementCase elementCase = elementCasePane.getEditingElementCase(); - - super.paint(g, c); - - if (!(elementCase instanceof FormElementCase)) { - return; - } - final Rectangle rectangle = getBoundsLineRect(elementCase, grid); - int width = getScaleWidth(rectangle.width) - columnWidthList.getRangeValue(0, horizontalValue).toPixI(resolution); - int height = getScaleHeight(rectangle.height) - rowHeightList.getRangeValue(0, verticalValue).toPixI(resolution); - drawBoundsLine(g2d, width, height); - addListener(grid, elementCasePane, width, height, rectangle.width, rectangle.height); - } - - private int getScaleWidth(int width) { - return width * resolution / DesignerUIModeConfig.getInstance().getScreenResolution(); - - } - - private int getScaleHeight(int height) { - return height * resolution / DesignerUIModeConfig.getInstance().getScreenResolution(); - } - - - /** - * 获取需要画线的矩形大小 - */ - private Rectangle getBoundsLineRect(TemplateElementCase elementCase, Grid grid) { - final Rectangle rectangle = new Rectangle(); - XElementCase xElementCase = FormDesignerUtil.getXelementCase(designer.getRootComponent(), (FormElementCase) elementCase); - if (xElementCase != null) { - rectangle.setBounds(xElementCase.getBounds()); - - //减去内边距的宽和高 - Insets insets = xElementCase.getInsets(); - rectangle.width -= insets.left + insets.right; - rectangle.height -= insets.top + insets.bottom; - - } - return rectangle; - } - - - private void addListener(Grid grid, ElementCasePane elementCasePane, int width, int height, int actualWidth, int actualHeight) { - addGridColumnListener(elementCasePane.getGridColumn(), width); - addGridRowListener(elementCasePane.getGridRow(), height); - addMouseListener(grid, width, height, actualWidth, actualHeight); - } - - - private void drawBoundsLine(Graphics2D g2d, int width, int height) { - g2d.setPaint(Color.black); - g2d.setStroke(GraphDrawHelper.getStroke(Constants.LINE_DASH_DOT)); - g2d.drawLine(0, height, width, height); - g2d.drawLine(width, 0, width, height); - } - - private void removeGridColumnListener(GridColumn column) { - MouseMotionListener[] mouseMotionListeners = column.getMouseMotionListeners(); - for (MouseMotionListener mouseMotionListener : mouseMotionListeners) { - if (mouseMotionListener instanceof com.fr.grid.GridColumnMouseHandler || mouseMotionListener instanceof GridLimitColumnMouseHandler) { - column.removeMouseMotionListener(mouseMotionListener); - } - } - MouseListener[] mouseListeners = column.getMouseListeners(); - for (MouseListener motionListener : mouseListeners) { - if (motionListener instanceof com.fr.grid.GridColumnMouseHandler || motionListener instanceof GridLimitColumnMouseHandler) { - column.removeMouseListener(motionListener); - } - } - } - - private void removeGridRowListener(GridRow row) { - MouseMotionListener[] mouseMotionListeners = row.getMouseMotionListeners(); - for (MouseMotionListener mouseMotionListener : mouseMotionListeners) { - if (mouseMotionListener instanceof com.fr.grid.GridRowMouseHandler || mouseMotionListener instanceof GridLimitRowMouseHandler) { - row.removeMouseMotionListener(mouseMotionListener); - } - } - MouseListener[] mouseListeners = row.getMouseListeners(); - for (MouseListener motionListener : mouseListeners) { - if (motionListener instanceof com.fr.grid.GridRowMouseHandler || motionListener instanceof GridLimitRowMouseHandler) { - row.removeMouseListener(motionListener); - } - } - } - - private void removeGridListener(Grid grid) { - MouseMotionListener[] mouseMotionListeners = grid.getMouseMotionListeners(); - for (MouseMotionListener mouseMotionListener : mouseMotionListeners) { - if (mouseMotionListener instanceof AdaptiveGridListener) { - grid.removeMouseMotionListener(mouseMotionListener); - break; - } - } - MouseListener[] mouseListeners = grid.getMouseListeners(); - for (MouseListener motionListener : mouseListeners) { - if (motionListener instanceof AdaptiveGridListener) { - grid.removeMouseListener(motionListener); - break; - } - } - MouseWheelListener[] mouseWheelListeners = grid.getMouseWheelListeners(); - for (MouseWheelListener mouseWheelListener : mouseWheelListeners) { - if (mouseWheelListener instanceof AdaptiveGridListener) { - grid.removeMouseWheelListener(mouseWheelListener); - break; - } - } - } - - private void addGridColumnListener(GridColumn column, int width) { - if (gridColumnMouseHandler != null) { - gridColumnMouseHandler.setLimit(width); - return; - } - removeGridColumnListener(column); - gridColumnMouseHandler = new GridLimitColumnMouseHandler(column, width); - column.addMouseListener(gridColumnMouseHandler); - column.addMouseMotionListener(gridColumnMouseHandler); - } - - - private void addGridRowListener(GridRow row, int height) { - if (gridRowMouseHandler != null) { - gridRowMouseHandler.setLimit(height); - return; - } - removeGridRowListener(row); - gridRowMouseHandler = new GridLimitRowMouseHandler(row, height); - row.addMouseMotionListener(gridRowMouseHandler); - row.addMouseListener(gridRowMouseHandler); - } - - - private void addMouseListener(Grid grid, int width, int height, int actualWidth, int actualHeight) { - if (adaptiveGridListener != null) { - adaptiveGridListener.resetBoundInfo(width, height, actualWidth, actualHeight); - return; - } - removeGridListener(grid); - adaptiveGridListener = new AdaptiveGridListener(grid, width, height, actualWidth, actualHeight); - grid.addMouseMotionListener(adaptiveGridListener); - grid.addMouseListener(adaptiveGridListener); - grid.addMouseWheelListener(adaptiveGridListener); - } - -} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePane.java b/designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePane.java index dbc4269d6..cdfceb3f4 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePane.java @@ -6,7 +6,7 @@ package com.fr.design.mainframe; import com.fr.base.BaseFormula; import com.fr.base.DynamicUnitList; import com.fr.base.Formula; -import com.fr.base.ScreenResolution; +import com.fr.base.NameStyle; import com.fr.base.Style; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignState; @@ -67,7 +67,6 @@ import com.fr.design.constants.UIConstants; import com.fr.design.designer.EditingState; import com.fr.design.designer.TargetComponent; import com.fr.design.file.HistoryTemplateListPane; -import com.fr.design.fit.DesignerUIModeConfig; import com.fr.design.fun.ElementUIProvider; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.imenu.UIPopupMenu; @@ -97,6 +96,7 @@ import com.fr.page.PageAttributeGetter; import com.fr.page.ReportPageAttrProvider; import com.fr.poly.creator.PolyElementCasePane; import com.fr.report.ReportHelper; +import com.fr.report.cell.CellElement; import com.fr.report.cell.FloatElement; import com.fr.report.cell.TemplateCellElement; import com.fr.report.cell.cellattr.core.RichText; @@ -133,6 +133,7 @@ import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.lang.reflect.Constructor; +import java.util.Iterator; import java.util.Set; import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; @@ -157,10 +158,10 @@ public abstract class ElementCasePane extends Tar // alex: private boolean supportDefaultParentCalculate = false; // GUI. - private Grid grid; - private GridRow gridRow; - private GridColumn gridColumn; - private GridCorner gridCorner; + protected Grid grid; + protected GridRow gridRow; + protected GridColumn gridColumn; + protected GridCorner gridCorner; private JScrollBar verScrollBar; private JScrollBar horScrollBar; // Visible @@ -365,7 +366,6 @@ public abstract class ElementCasePane extends Tar } } - public void setResolution(int resolution) { this.resolution = resolution; } @@ -1374,6 +1374,33 @@ public abstract class ElementCasePane extends Tar return cellNeedTOFormat; } + public void traverseSelectedCellElements(TemplateCellElementVisitor visitor) { + Selection selection = getSelection(); + if (!(selection instanceof CellSelection)) { + return; + } + CellSelection cs = (CellSelection) selection; + TemplateElementCase elementCase = getEditingElementCase(); + int cellRectangleCount = cs.getCellRectangleCount(); + + for (int rect = 0; rect < cellRectangleCount; rect++) { + Rectangle cellRectangle = cs.getCellRectangle(rect); + for (int j = 0; j < cellRectangle.height; j++) { + for (int i = 0; i < cellRectangle.width; i++) { + int column = i + cellRectangle.x; + int row = j + cellRectangle.y; + + TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); + visitor.visit(column, row, cellElement); + } + } + } + } + + public interface TemplateCellElementVisitor { + void visit(int column, int row, TemplateCellElement cellElement); + } + private class ElementCaseEditingState implements EditingState { protected Selection selection; diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellStylePane.java b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellStylePane.java index c28c00de5..24ea3209d 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellStylePane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellStylePane.java @@ -1,22 +1,23 @@ package com.fr.design.mainframe.cell.settingpane; import com.fr.base.CellBorderStyle; +import com.fr.base.NameStyle; import com.fr.base.Style; import com.fr.design.actions.utils.ReportActionUtils; import com.fr.design.constants.UIConstants; -import com.fr.design.gui.style.BorderPane; +import com.fr.design.mainframe.ElementCasePane; import com.fr.design.mainframe.cell.settingpane.style.StylePane; import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase; import com.fr.design.style.BorderUtils; import com.fr.design.utils.gui.GUICoreUtils; - import com.fr.report.cell.TemplateCellElement; import com.fr.report.elementcase.TemplateElementCase; -import javax.swing.*; +import javax.swing.JFrame; +import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import java.awt.*; +import java.awt.BorderLayout; /** * @author zhou @@ -71,29 +72,56 @@ public class CellStylePane extends AbstractCellAttrPane { @Override public void updateBeans() { - Object[] selectionCellBorderObjects = BorderUtils.createCellBorderObject(elementCasePane); + // 因为存在框选多个单元格的情况,跟随主题切换到自定义的行为似乎不太适合由updateBeans完成,它更像是个工具栏上的Action. + // 但它又会触发updateBeans... + boolean isSwitchToCustomStyleAction = stylePane.isFollowingThemeSettingChanged() && !stylePane.isFollowingTheme(); + if (isSwitchToCustomStyleAction) { + switchCellStylesToCustom(); + return; + } + updateCellStylesByPaneSettings(); + } + + private void switchCellStylesToCustom() { TemplateElementCase elementCase = elementCasePane.getEditingElementCase(); - int cellRectangleCount = cs.getCellRectangleCount(); - for (int rect = 0; rect < cellRectangleCount; rect++) { - Rectangle cellRectangle = cs.getCellRectangle(rect); - for (int j = 0; j < cellRectangle.height; j++) { - for (int i = 0; i < cellRectangle.width; i++) { - int column = i + cellRectangle.x; - int row = j + cellRectangle.y; - TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); - if (cellElement == null) { - cellElement = DefaultThemedTemplateCellElementCase.createInstance(column, row); - elementCase.addCellElement(cellElement); - } - Style style = stylePane.updateBean(); - cellElement.setStyle(style); + elementCasePane.traverseSelectedCellElements(new ElementCasePane.TemplateCellElementVisitor() { + @Override + public void visit(int column, int row, TemplateCellElement cellElement) { + if (cellElement == null) { + cellElement = DefaultThemedTemplateCellElementCase.createInstance(column, row); + elementCase.addCellElement(cellElement); } + Style style = cellElement.getStyle(); + if (style instanceof NameStyle) { + style = ((NameStyle) style).getRealStyle(); + } + if (style == null) { + style = Style.DEFAULT_STYLE; + } + cellElement.setStyle(style); } - } + }); + } + + private void updateCellStylesByPaneSettings() { + Object[] oldSelectionCellBorderObjects = BorderUtils.createCellBorderObject(elementCasePane); + + TemplateElementCase elementCase = elementCasePane.getEditingElementCase(); + elementCasePane.traverseSelectedCellElements(new ElementCasePane.TemplateCellElementVisitor() { + @Override + public void visit(int column, int row, TemplateCellElement cellElement) { + if (cellElement == null) { + cellElement = DefaultThemedTemplateCellElementCase.createInstance(column, row); + elementCase.addCellElement(cellElement); + } + Style style = stylePane.updateBean(); + cellElement.setStyle(style); + } + }); // border必须特别处理 - CellBorderStyle cellBorderStyle = stylePane.updateBorderStyle(); - if (cellBorderStyle != null) { - BorderUtils.update(elementCasePane, selectionCellBorderObjects, cellBorderStyle); + CellBorderStyle newCellBorderStyle = stylePane.updateBorderStyle(); + if (newCellBorderStyle != null) { + BorderUtils.update(elementCasePane, oldSelectionCellBorderObjects, newCellBorderStyle); } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java index c6613befa..7f382ed44 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java @@ -51,6 +51,7 @@ public class StylePane extends BasicPane implements UIObserver { private final List observerListeners = new ArrayList<>(); private Style backupStyleFromPopulating = Style.DEFAULT_STYLE; + private boolean isFollowingThemeSettingChanged = false; public StylePane() { followingThemeButtonGroup = new UIButtonGroup<>(FOLLOWING_THEME_STRING_ARRAYS); @@ -77,6 +78,7 @@ public class StylePane extends BasicPane implements UIObserver { followingThemeButtonGroup.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { + isFollowingThemeSettingChanged = true; AttributeChangeUtils.changeComposedUI(StylePane.this, false, new AttributeChangeUtils.UIChangeAction() { @Override public void changeComposedUI() { @@ -85,6 +87,7 @@ public class StylePane extends BasicPane implements UIObserver { } }); fireStateChanged(); + isFollowingThemeSettingChanged = false; } }); @@ -103,25 +106,33 @@ public class StylePane extends BasicPane implements UIObserver { cardLayout.show(contentPane, FOLLOWING_THEME_STRING_ARRAYS[selectedIndex]); if (!isFollowingTheme) { // 对于同一个单元格,跟随主题切换到自定义,自定义中的配置与其保持一致 - NameStyle lastSelectedNameStyle = nameStyleListPane.updateNameStyle(); - if (lastSelectedNameStyle != null) { - Style lastSelectedRealStyle = lastSelectedNameStyle.getRealStyle(); - try { - lastSelectedRealStyle = (Style) lastSelectedRealStyle.clone(); - if (lastSelectedRealStyle != null) { - customStylePane.populateBean(lastSelectedRealStyle); - customStylePane.dealWithBorder(); - } - } catch (CloneNotSupportedException ex) { - FineLoggerFactory.getLogger().error(ex.getMessage(), ex); - } - } + syncCustomStylePaneBySelectedNameStyle(); } else { // 对于同一个单元格,自定义切换到跟随主题,跟随主题选中"默认"样式,并使用默认样式设置选中的单元格 nameStyleListPane.reset(); } } + private void syncCustomStylePaneBySelectedNameStyle() { + NameStyle lastSelectedNameStyle = nameStyleListPane.updateNameStyle(); + if (lastSelectedNameStyle != null) { + Style lastSelectedRealStyle = lastSelectedNameStyle.getRealStyle(); + try { + lastSelectedRealStyle = (Style) lastSelectedRealStyle.clone(); + if (lastSelectedRealStyle != null) { + customStylePane.populateBean(lastSelectedRealStyle); + customStylePane.dealWithBorder(); + } + } catch (CloneNotSupportedException ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } + } + } + + public boolean isFollowingThemeSettingChanged() { + return isFollowingThemeSettingChanged; + } + protected JPanel createTabbedContentPane() { JPanel contentPane = new JPanel(cardLayout) { @Override @@ -161,14 +172,22 @@ public class StylePane extends BasicPane implements UIObserver { return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style"); } - public void setSelectedIndex(int index) { + public boolean isFollowingTheme() { + return getSelectedIndex() == 0; + } + + public void setFollowingTheme(boolean followingTheme) { + setSelectedIndex(followingTheme ? 0 : 1); + } + + private void setSelectedIndex(int index) { if (0 <= index && index < FOLLOWING_THEME_STRING_ARRAYS.length) { followingThemeButtonGroup.setSelectedIndex(index); cardLayout.show(contentPane, FOLLOWING_THEME_STRING_ARRAYS[index]); } } - public int getSelectedIndex() { + private int getSelectedIndex() { return followingThemeButtonGroup.getSelectedIndex(); } @@ -185,11 +204,11 @@ public class StylePane extends BasicPane implements UIObserver { } public void setSelctedByName(String id) { - setSelectedIndex(ComparatorUtils.equals(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Custom"), id)? 1 : 0); + setFollowingTheme(!ComparatorUtils.equals(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Custom"), id)); } public CellBorderStyle updateBorderStyle() { - if (getSelectedIndex() == 0) { + if (isFollowingTheme()) { return nameStyleListPane.updateBorderStyle(); } else if (customStylePane.isBorderPaneSelected()) { return customStylePane.updateBorderStyle(); @@ -199,7 +218,7 @@ public class StylePane extends BasicPane implements UIObserver { public Style updateBean() { Style finalStyle = null; - if (getSelectedIndex() == 0) { + if (isFollowingTheme()) { finalStyle = nameStyleListPane.updateNameStyle(); } if (finalStyle == null) { @@ -215,7 +234,7 @@ public class StylePane extends BasicPane implements UIObserver { if (style instanceof NameStyle) { NameStyle nameStyle = (NameStyle) style; - setSelectedIndex(0); + setFollowingTheme(true); nameStyleListPane.populateNameStyle(nameStyle); Style realStyle = nameStyle.getRealStyle(); try { @@ -225,7 +244,7 @@ public class StylePane extends BasicPane implements UIObserver { e.printStackTrace(); } } else { - setSelectedIndex(1); + setFollowingTheme(false); customStylePane.populateBean(style); } //单元格配置界面是单例 所以直接在populate的时候把跟随主题的按钮组设置不可见 diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCaseDesigner.java b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCaseDesigner.java index 43c66d8c8..5be6362a4 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCaseDesigner.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCaseDesigner.java @@ -13,7 +13,6 @@ import com.fr.design.designer.EditingState; import com.fr.design.designer.TargetComponent; import com.fr.design.event.TargetModifiedEvent; import com.fr.design.event.TargetModifiedListener; -import com.fr.design.fit.DesignerUIModeConfig; import com.fr.design.gui.frpane.HyperlinkGroupPane; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.AuthorityEditPane; diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCasePaneDelegate.java b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCasePaneDelegate.java index 55d11fe7d..5961700e2 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCasePaneDelegate.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCasePaneDelegate.java @@ -6,8 +6,11 @@ import com.fr.design.actions.core.ActionFactory; import com.fr.design.actions.form.FormECBackgroundAction; import com.fr.design.actions.form.FormECColumnsAction; import com.fr.design.actions.form.FormECFrozenAction; +import com.fr.design.designer.creator.XElementCase; import com.fr.design.event.TargetModifiedEvent; import com.fr.design.event.TargetModifiedListener; +import com.fr.design.fit.NewUIModeCellElementPainter; +import com.fr.design.fit.common.FormDesignerUtil; import com.fr.design.gui.frpane.HyperlinkGroupPane; import com.fr.design.mainframe.*; import com.fr.design.mainframe.cell.QuickEditorRegion; @@ -16,27 +19,36 @@ import com.fr.design.menu.MenuDef; import com.fr.design.menu.ShortCut; import com.fr.design.menu.ToolBarDef; import com.fr.design.present.ConditionAttributesGroupPane; +import com.fr.form.fit.common.LightTool; import com.fr.form.main.Form; import com.fr.grid.Grid; +import com.fr.grid.GridColumn; +import com.fr.grid.GridCorner; +import com.fr.grid.GridRow; import com.fr.page.ReportSettingsProvider; +import com.fr.report.elementcase.TemplateElementCase; import com.fr.report.worksheet.FormElementCase; import com.fr.design.selection.SelectionEvent; import com.fr.design.selection.SelectionListener; import javax.swing.JComponent; import javax.swing.JPanel; +import java.awt.Insets; +import java.awt.Rectangle; /** */ public class FormElementCasePaneDelegate extends ElementCasePane{ + public FormElementCasePaneDelegate(FormElementCase sheet, Form form) { super(sheet); - this.getGrid().setPaginateLineShowType(form.getFormMobileAttr().isMobileOnly() ? Grid.SINGLE_HORIZONTAL_PAGINATE_LINE : Grid.NO_PAGINATE_LINE); - + if (LightTool.containNewFormFlag(form)){ + this.getGrid().setCellElementPainter(new NewUIModeCellElementPainter()); + } this.addSelectionChangeListener(new SelectionListener() { @Override public void selectionChanged(SelectionEvent e) { @@ -55,6 +67,42 @@ public class FormElementCasePaneDelegate extends ElementCasePane { - private GridColumnMouseHandler gridColumnMouseHandler; + private GridColumnMouseHandler gridColumnMouseHandler; + private int adsorbWidth; - public GridColumn(int resolution) { - super(resolution); - } + public GridColumn(int resolution) { + this(resolution, 0); + } - @Override - protected void initByConstructor() { - gridColumnMouseHandler = new GridColumnMouseHandler(this); - this.addMouseListener(gridColumnMouseHandler); - this.addMouseMotionListener(gridColumnMouseHandler); - this.updateUI(); - } + public GridColumn(int resolution, int adsorbWidth) { + super(resolution); + this.adsorbWidth = adsorbWidth; + } + @Override + protected void initByConstructor() { + this.updateUI(); + } + @Override + public String getDisplay(int index) { + return StableUtils.convertIntToABC(index + 1); + } - @Override - public String getDisplay(int index) { - return StableUtils.convertIntToABC(index + 1); - } + @Override + public void updateUI() { + this.removeMouseListener(gridColumnMouseHandler); + this.removeMouseMotionListener(gridColumnMouseHandler); + gridColumnMouseHandler = new GridColumnMouseHandler(this, adsorbWidth); + this.addMouseListener(gridColumnMouseHandler); + this.addMouseMotionListener(gridColumnMouseHandler); + this.setUI(new GridColumnUI(resolution)); + } - @Override - public void updateUI() { - this.removeMouseListener(gridColumnMouseHandler); - this.removeMouseMotionListener(gridColumnMouseHandler); - gridColumnMouseHandler = new GridColumnMouseHandler(this); - this.addMouseListener(gridColumnMouseHandler); - this.addMouseMotionListener(gridColumnMouseHandler); - this.setUI(new GridColumnUI(resolution)); - } + /** + * Gets the preferred size. + */ + @Override + public Dimension getPreferredSize() { + ElementCasePane reportPane = this.getElementCasePane(); + float time = (float) reportPane.getResolution() / DesignerUIModeConfig.getInstance().getScreenResolution(); + if (!reportPane.isColumnHeaderVisible()) { + return new Dimension(0, 0); + } - /** - * Gets the preferred size. - */ - @Override - public Dimension getPreferredSize() { - ElementCasePane reportPane = this.getElementCasePane(); - float time = (float)reportPane.getResolution()/ DesignerUIModeConfig.getInstance().getScreenResolution(); - if (!reportPane.isColumnHeaderVisible()) { - return new Dimension(0, 0); - } - - return new Dimension(super.getPreferredSize().width, (int) (GraphHelper.getFontMetrics(this.getFont()).getHeight() * time + SIZE_ADJUST)); - } + return new Dimension(super.getPreferredSize().width, (int) (GraphHelper.getFontMetrics(this.getFont()).getHeight() * time + SIZE_ADJUST)); + } } diff --git a/designer-realize/src/main/java/com/fr/grid/GridColumnMouseHandler.java b/designer-realize/src/main/java/com/fr/grid/GridColumnMouseHandler.java index bc5b54c90..a6b38dc81 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridColumnMouseHandler.java +++ b/designer-realize/src/main/java/com/fr/grid/GridColumnMouseHandler.java @@ -9,23 +9,34 @@ import java.awt.event.MouseEvent; import javax.swing.SwingUtilities; import com.fr.base.DynamicUnitList; import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.mainframe.ElementCasePane; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.Selection; import com.fr.report.ReportHelper; import com.fr.report.elementcase.ElementCase; +import com.fr.report.elementcase.TemplateElementCase; import com.fr.stable.ColumnRow; +import com.fr.stable.unit.FU; +import com.fr.stable.unit.UNIT; /** * peter:处理对GridColumn的Mouse事件. */ public class GridColumnMouseHandler extends AbstractGridHeaderMouseHandler { + private final int adsorbWidth; + public GridColumnMouseHandler(GridColumn gridColumn) { - super(gridColumn); - this.resolution = gridColumn.resolution; + this(gridColumn, 0); } + public GridColumnMouseHandler(GridColumn gridColumn, int adsorbWidth) { + super(gridColumn); + this.adsorbWidth = adsorbWidth; + this.resolution = gridColumn.resolution; + } + public void setResolution(int resolution){ this.resolution = resolution; } @@ -40,6 +51,24 @@ public class GridColumnMouseHandler extends AbstractGridHeaderMouseHandler { } } + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + if (this.adsorbWidth <= 0) { + return; + } + ElementCasePane elementCasePane = this.gHeader.getElementCasePane(); + TemplateElementCase editingElementCase = elementCasePane.getEditingElementCase(); + double adsorbWidthWithResolution = this.adsorbWidth * (resolution * 1D / DesignerUIModeConfig.getInstance().getScreenResolution()); + + int dragIndex = getDragIndex(e); + if (Math.abs(e.getX() - adsorbWidthWithResolution) < FUZZY_EDGE && dragIndex >= 0) { + UNIT oldValue = editingElementCase.getColumnWidth(dragIndex); + editingElementCase.setColumnWidth(dragIndex, oldValue.add(FU.valueOfPix((int) (adsorbWidthWithResolution- e.getX()), resolution))); + } + elementCasePane.repaint(); + } + protected int doChooseFrom() { return CellSelection.CHOOSE_COLUMN; diff --git a/designer-realize/src/main/java/com/fr/grid/GridColumnUI.java b/designer-realize/src/main/java/com/fr/grid/GridColumnUI.java index 088c8f220..6c401e925 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridColumnUI.java +++ b/designer-realize/src/main/java/com/fr/grid/GridColumnUI.java @@ -16,7 +16,7 @@ import com.fr.base.ScreenResolution; import com.fr.base.vcs.DesignerMode; import com.fr.cache.list.IntList; import com.fr.design.constants.UIConstants; -import com.fr.design.fit.DesignerUIModeConfig; +import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.mainframe.ElementCasePane; import com.fr.design.roleAuthority.ReportAndFSManagePane; import com.fr.grid.selection.Selection; diff --git a/designer-realize/src/main/java/com/fr/grid/GridCorner.java b/designer-realize/src/main/java/com/fr/grid/GridCorner.java index 4d1d393b7..2bbe3d9df 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridCorner.java +++ b/designer-realize/src/main/java/com/fr/grid/GridCorner.java @@ -4,9 +4,9 @@ package com.fr.grid; import com.fr.base.GraphHelper; -import com.fr.base.ScreenResolution; + import com.fr.design.constants.UIConstants; -import com.fr.design.fit.DesignerUIModeConfig; +import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.mainframe.ElementCasePane; import javax.swing.event.MouseInputListener; diff --git a/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java b/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java index c2c186114..45f774823 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java +++ b/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java @@ -2,11 +2,10 @@ package com.fr.grid; import com.fr.base.BaseUtils; import com.fr.base.DynamicUnitList; -import com.fr.base.ScreenResolution; import com.fr.base.vcs.DesignerMode; import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.constants.UIConstants; -import com.fr.design.fit.DesignerUIModeConfig; +import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.EastRegionContainerPane; import com.fr.design.mainframe.ElementCasePane; @@ -78,8 +77,18 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous private int[] resizingBackupBounds = null; - protected GridMouseAdapter(Grid grid) { + private double adsorbWidth = 0D; + + private double adsorbHeight = 0D; + + private JWindow tipWindow = null; + private JToolTip tip = null; + + + protected GridMouseAdapter(Grid grid, double adsorbWidth, double adsorbHeight) { this.grid = grid; + this.adsorbWidth = adsorbWidth; + this.adsorbHeight = adsorbHeight; } /** @@ -330,8 +339,63 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous } lastMouseMoveTime = systemCurrentTime;// 记录最后一次的时间. mouseMoveOnGrid(evt.getX(), evt.getY()); + dealAdsorb(evt); } + private void dealAdsorb(final MouseEvent e) { + if (adsorbWidth <= 0 || adsorbHeight <= 0) { + return; + } + int verticalValue = grid.getVerticalValue(); + int horizontalValue = grid.getHorizontalValue(); + ElementCasePane reportPane = grid.getElementCasePane(); + TemplateElementCase report = reportPane.getEditingElementCase(); + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); + DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); + double width = adsorbWidth * (resolution * 1.0D / DesignerUIModeConfig.getInstance().getScreenResolution()) + - columnWidthList.getRangeValue(0, horizontalValue).toPixI(this.grid.getResolution()); + double height = adsorbHeight * (resolution * 1.0D / DesignerUIModeConfig.getInstance().getScreenResolution()) + - rowHeightList.getRangeValue(0, verticalValue).toPixI(this.grid.getResolution()); + if (Math.abs(e.getX() - width) < 5 && e.getY() >= 0 && e.getY() < height) { + Point convertPoint = new Point((int) width, 0); + SwingUtilities.convertPointToScreen(convertPoint, grid); + showToolTip(grid, e, adsorbWidth + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Px"), convertPoint); + return; + } else { + hideToolTip(); + } + if (Math.abs(e.getY() - height) < 5 && e.getX() >= 0 && e.getX() < width) { + Point convertPoint = new Point(0, (int) height); + SwingUtilities.convertPointToScreen(convertPoint, grid); + showToolTip(grid, e, adsorbHeight + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Px"), convertPoint); + } else { + hideToolTip(); + } + } + + private void showToolTip(Grid grid, MouseEvent evt, String text, Point tipLocation) { + if (tipWindow == null) { + tipWindow = new JWindow(); + + + tip = grid.createToolTip(); + tip.setBorder(BorderFactory.createEmptyBorder()); + tipWindow.getContentPane().add(tip, BorderLayout.CENTER); + } + tip.setTipText(text); + tip.setForeground(Color.decode("#88ACC6")); + tipWindow.setLocation(tipLocation.x, tipLocation.y); + tipWindow.pack(); + tipWindow.setVisible(true); + } + + private void hideToolTip() { + if (tipWindow != null) { + tipWindow.setVisible(false); + } + } + + /** * @param evt */ @@ -879,7 +943,7 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous * @param e */ public void mouseWheelMoved(MouseWheelEvent e) { - + hideToolTip(); } /** @@ -898,5 +962,6 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous * @param e */ public void mouseExited(MouseEvent e) { + hideToolTip(); } } diff --git a/designer-realize/src/main/java/com/fr/grid/GridRow.java b/designer-realize/src/main/java/com/fr/grid/GridRow.java index a85c3c398..0ec5fdab2 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridRow.java +++ b/designer-realize/src/main/java/com/fr/grid/GridRow.java @@ -6,75 +6,74 @@ package com.fr.grid; import java.awt.Dimension; import com.fr.base.GraphHelper; -import com.fr.base.ScreenResolution; -import com.fr.design.ExtraDesignClassManager; -import com.fr.design.fit.DesignerUIModeConfig; -import com.fr.design.fun.GridUIProcessor; +import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.mainframe.ElementCasePane; -import javax.swing.plaf.ComponentUI; - /** * GridRow used to paint and edit grid row. - * + * * @editor zhou * @since 2012-3-22下午6:12:03 */ public class GridRow extends GridHeader { - private static final int MAX = 4; - private GridRowMouseHandler gridRowMouseHandler; + private static final int MAX = 4; + private int adsorbHeight; + private GridRowMouseHandler gridRowMouseHandler; + + public GridRow(int resolution) { + this(resolution, 0); + } + + public GridRow(int resolution, int adsorbHeight) { + super(resolution); + this.adsorbHeight = adsorbHeight; + } - public GridRow(int resolution) { - super(resolution); - } - @Override - protected void initByConstructor() { - gridRowMouseHandler = new GridRowMouseHandler(this); - this.addMouseListener(gridRowMouseHandler); - this.addMouseMotionListener(gridRowMouseHandler); - this.updateUI(); - } + @Override + protected void initByConstructor() { + this.updateUI(); + } - @Override - public Integer getDisplay(int index) { - return new Integer(index + 1); - } + @Override + public Integer getDisplay(int index) { + return new Integer(index + 1); + } - @Override - public void updateUI() { - this.removeMouseListener(gridRowMouseHandler); - this.removeMouseMotionListener(gridRowMouseHandler); - gridRowMouseHandler = new GridRowMouseHandler(this); - this.addMouseListener(gridRowMouseHandler); - this.addMouseMotionListener(gridRowMouseHandler); - this.setUI(new GridRowUI(resolution)); - } + @Override + public void updateUI() { + this.removeMouseListener(gridRowMouseHandler); + this.removeMouseMotionListener(gridRowMouseHandler); + gridRowMouseHandler = new GridRowMouseHandler(this, adsorbHeight); + this.addMouseListener(gridRowMouseHandler); + this.addMouseMotionListener(gridRowMouseHandler); + this.setUI(new GridRowUI(resolution)); + } - /** - * Gets the preferred size. - */ - @Override - public Dimension getPreferredSize() { - ElementCasePane reportPane = this.getElementCasePane(); - float time = (float)reportPane.getResolution()/ DesignerUIModeConfig.getInstance().getScreenResolution(); - if (!(reportPane.isRowHeaderVisible())) { - return new Dimension(0, 0); - } + /** + * Gets the preferred size. + */ + @Override + public Dimension getPreferredSize() { + ElementCasePane reportPane = this.getElementCasePane(); + float time = (float) reportPane.getResolution() / DesignerUIModeConfig.getInstance().getScreenResolution(); + if (!(reportPane.isRowHeaderVisible())) { + return new Dimension(0, 0); + } - int maxCharNumber = this.caculateMaxCharNumber(reportPane); - return new Dimension((int) (maxCharNumber * GraphHelper.getFontMetrics(this.getFont()).charWidth('M') * time), super.getPreferredSize().height); - } + int maxCharNumber = this.caculateMaxCharNumber(reportPane); + return new Dimension((int) (maxCharNumber * GraphHelper.getFontMetrics(this.getFont()).charWidth('M') * time), super.getPreferredSize().height); + } - /** - * Calculates max char number. - */ - private int caculateMaxCharNumber(ElementCasePane reportPane) { - int maxCharNumber = MAX; - maxCharNumber = Math.max(maxCharNumber, ("" + (reportPane.getGrid().getVerticalValue() + reportPane.getGrid().getVerticalExtent())).length() + 1); + /** + * Calculates max char number. + */ + private int caculateMaxCharNumber(ElementCasePane reportPane) { + int maxCharNumber = MAX; + maxCharNumber = Math.max(maxCharNumber, ("" + (reportPane.getGrid().getVerticalValue() + reportPane.getGrid().getVerticalExtent())).length() + 1); - return maxCharNumber; - } + return maxCharNumber; + } } \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/grid/GridRowMouseHandler.java b/designer-realize/src/main/java/com/fr/grid/GridRowMouseHandler.java index b6e229247..e828c2a4a 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridRowMouseHandler.java +++ b/designer-realize/src/main/java/com/fr/grid/GridRowMouseHandler.java @@ -9,20 +9,30 @@ import javax.swing.SwingUtilities; import com.fr.base.DynamicUnitList; import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.mainframe.ElementCasePane; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.Selection; import com.fr.report.ReportHelper; import com.fr.report.elementcase.ElementCase; +import com.fr.report.elementcase.TemplateElementCase; import com.fr.stable.ColumnRow; +import com.fr.stable.unit.FU; +import com.fr.stable.unit.UNIT; /** * peter:处理对GridRow的Mouse事件. */ public class GridRowMouseHandler extends AbstractGridHeaderMouseHandler { + private final int adsorbHeight; public GridRowMouseHandler(GridRow gridRow) { + this(gridRow, 0); + } + + public GridRowMouseHandler(GridRow gridRow, int adsorbHeight) { super(gridRow); + this.adsorbHeight = adsorbHeight; } @Override @@ -36,6 +46,23 @@ public class GridRowMouseHandler extends AbstractGridHeaderMouseHandler { } + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + if (this.adsorbHeight <= 0) { + return; + } + ElementCasePane elementCasePane = this.gHeader.getElementCasePane(); + TemplateElementCase editingElementCase = elementCasePane.getEditingElementCase(); + double adsorbHeightWithResolution = this.adsorbHeight * (resolution * 1D / DesignerUIModeConfig.getInstance().getScreenResolution()); + int dragIndex = getDragIndex(e); + if (Math.abs(e.getY() - adsorbHeightWithResolution) < FUZZY_EDGE && dragIndex >= 0) { + UNIT oldValue = editingElementCase.getRowHeight(dragIndex); + editingElementCase.setRowHeight(dragIndex, oldValue.add(FU.valueOfPix((int) (adsorbHeightWithResolution - e.getY()), resolution))); + } + elementCasePane.repaint(); + } + protected int doChooseFrom() { return CellSelection.CHOOSE_ROW; } diff --git a/designer-realize/src/main/java/com/fr/grid/GridRowUI.java b/designer-realize/src/main/java/com/fr/grid/GridRowUI.java index 6c2fed6d0..19f4d76df 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridRowUI.java +++ b/designer-realize/src/main/java/com/fr/grid/GridRowUI.java @@ -8,7 +8,7 @@ import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; -import com.fr.design.fit.DesignerUIModeConfig; +import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.stable.AssistUtils; import com.fr.base.BaseUtils; import com.fr.base.DynamicUnitList; diff --git a/designer-realize/src/main/java/com/fr/grid/GridUI.java b/designer-realize/src/main/java/com/fr/grid/GridUI.java index 431c6de1e..c6ed5e416 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridUI.java +++ b/designer-realize/src/main/java/com/fr/grid/GridUI.java @@ -14,6 +14,7 @@ import com.fr.design.base.mode.DesignModeContext; import com.fr.design.constants.UIConstants; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.mainframe.ElementCasePane; import com.fr.design.mainframe.JTemplate; import com.fr.design.roleAuthority.ReportAndFSManagePane; @@ -48,6 +49,7 @@ import com.fr.report.worksheet.WorkSheet; import com.fr.stable.AssistUtils; import com.fr.stable.ColumnRow; import com.fr.stable.Constants; +import com.fr.stable.GraphDrawHelper; import com.fr.stable.script.CalculatorUtils; import com.fr.stable.unit.FU; import com.fr.stable.unit.UNIT; @@ -92,6 +94,7 @@ public class GridUI extends ComponentUI { protected int verticalEndValue; protected int horizontalEndValue; protected DrawFlowRect drawFlowRect; + // paint的辅助类 protected List paintCellElementList = new ArrayList(); protected List paintCellElementRectangleList = new ArrayList(); @@ -1147,6 +1150,7 @@ public class GridUI extends ComponentUI { Graphics2D g2d = (Graphics2D) g; Grid grid = (Grid) c; + this.painter = grid.getCellElementPainter(); // 取得ElementCasePane.ElementCase ElementCasePane elementCasePane = grid.getElementCasePane(); @@ -1191,9 +1195,37 @@ public class GridUI extends ComponentUI { paintWatermark(g2d, ((WorkSheet) elementCase).getBook()); } + //绘制吸附辅助线 + paintAdsorbLines(g2d, grid); + grid.ajustEditorComponentBounds(); // refresh size } + //绘制吸附辅助线 + private void paintAdsorbLines(Graphics2D g2d, Grid grid) { + int verticalValue = grid.getVerticalValue(); + int horizontalValue = grid.getHorizontalValue(); + if (grid.getAdsorbWidth() <= 0 || grid.getAdsorbHeight() <= 0) { + return; + } + int width = (int) (grid.getAdsorbWidth() * (resolution * 1.0D / DesignerUIModeConfig.getInstance().getScreenResolution()) + - columnWidthList.getRangeValue(0, horizontalValue).toPixI(resolution)); + int height = (int) (grid.getAdsorbHeight() * (resolution * 1.0D / DesignerUIModeConfig.getInstance().getScreenResolution()) + - rowHeightList.getRangeValue(0, verticalValue).toPixI(resolution)); + drawBoundsLine(g2d, width, height); + } + + private void drawBoundsLine(Graphics2D g2d, int width, int height) { + Paint oldPaint = g2d.getPaint(); + Stroke oldStroke = g2d.getStroke(); + g2d.setPaint(Color.black); + g2d.setStroke(GraphDrawHelper.getStroke(Constants.LINE_DASH_DOT)); + g2d.drawLine( 0, height, width, height); + g2d.drawLine( width, 0, width, height); + g2d.setPaint(oldPaint); + g2d.setStroke(oldStroke); + } + // 绘制水印 private void paintWatermark(Graphics2D g2d, FineBook book) { WatermarkAttr watermark = ReportUtils.getWatermarkAttrFromTemplateAndGlobal(book); diff --git a/designer-realize/src/main/java/com/fr/grid/GridUtils.java b/designer-realize/src/main/java/com/fr/grid/GridUtils.java index 31ceacd7a..21b032265 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridUtils.java +++ b/designer-realize/src/main/java/com/fr/grid/GridUtils.java @@ -5,7 +5,7 @@ import com.fr.base.ScreenResolution; import com.fr.design.cell.clipboard.CellElementsClip; import com.fr.design.cell.clipboard.ElementsTransferable; import com.fr.design.cell.clipboard.FloatElementsClip; -import com.fr.design.fit.DesignerUIModeConfig; +import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.mainframe.ElementCasePane; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.ComparatorUtils; diff --git a/designer-realize/src/test/java/com/fr/design/mainframe/app/DesignerAppUtilsTest.java b/designer-realize/src/test/java/com/fr/design/mainframe/app/DesignerAppUtilsTest.java index 46aa574e9..f47d18d34 100644 --- a/designer-realize/src/test/java/com/fr/design/mainframe/app/DesignerAppUtilsTest.java +++ b/designer-realize/src/test/java/com/fr/design/mainframe/app/DesignerAppUtilsTest.java @@ -3,15 +3,11 @@ package com.fr.design.mainframe.app; import com.fr.invoke.Reflect; import com.fr.plugin.context.PluginMarker; import com.fr.plugin.context.PluginMarkerAdapter; -import com.fr.plugin.engine.remote.PluginRemoteSync; import com.fr.stable.TemplateIOErrorContextHolder; import com.fr.third.guava.collect.Multimap; -import org.easymock.EasyMock; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; -import org.powermock.api.easymock.PowerMock; -import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import java.util.Collection; @@ -24,13 +20,12 @@ import java.util.HashSet; * Created by vito on 2021/5/31 */ @RunWith(PowerMockRunner.class) -@PrepareForTest({PluginRemoteSync.class}) public class DesignerAppUtilsTest { @Test public void testDealWithErrorDetailMultiLineAndCache() { TemplateIOErrorContextHolder.registerPluginNameMap(new HashMap() {{ put("2", "好用的插件"); - }},new HashSet<>()); + }}, new HashSet<>()); TemplateIOErrorContextHolder.addNeedEnablePlugin(PluginMarkerAdapter.create("1", "1.0", "1插件")); TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("2", "1.0")); TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("3", "1.0")); @@ -47,7 +42,7 @@ public class DesignerAppUtilsTest { public void testInvalidatePlugins() { TemplateIOErrorContextHolder.registerPluginNameMap(new HashMap() {{ put("2", "好用的插件"); - }},new HashSet<>()); + }}, new HashSet<>()); TemplateIOErrorContextHolder.addNeedEnablePlugin(PluginMarkerAdapter.create("1", "1.0", "1插件")); TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("2", "1.0")); TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("3", "1.0")); @@ -60,19 +55,19 @@ public class DesignerAppUtilsTest { } @Test - public void testRearrange(){ + public void testRearrange() { // 远程插件模拟注册 - PluginRemoteSync pluginRemoteSync = EasyMock.createMock(PluginRemoteSync.class); - EasyMock.expect(pluginRemoteSync.getPluginRemoteStatusByIdIndex()).andReturn(new HashMap(){{ - put("com.fr.plugin1", Reflect.on(PluginRemoteSync.PluginStatus.class).call("create","com.fr.plugin1","1",true).get()); - put("com.fr.plugin2", Reflect.on(PluginRemoteSync.PluginStatus.class).call("create","com.fr.plugin2","1",true).get()); - put("com.fr.plugin3", Reflect.on(PluginRemoteSync.PluginStatus.class).call("create","com.fr.plugin3","1",false).get()); - put("com.fr.plugin4", Reflect.on(PluginRemoteSync.PluginStatus.class).call("create","com.fr.plugin4","1",false).get()); - }}).anyTimes(); - EasyMock.replay(pluginRemoteSync); - PowerMock.mockStaticPartial(PluginRemoteSync.class, "getInstance"); - EasyMock.expect(PluginRemoteSync.getInstance()).andReturn(pluginRemoteSync).anyTimes(); - PowerMock.replay(PluginRemoteSync.class); +// PluginRemoteSync pluginRemoteSync = EasyMock.createMock(PluginRemoteSync.class); +// EasyMock.expect(pluginRemoteSync.getPluginRemoteStatusByIdIndex()).andReturn(new HashMap(){{ +// put("com.fr.plugin1", Reflect.on(PluginRemoteSync.PluginStatus.class).call("create","com.fr.plugin1","1",true).get()); +// put("com.fr.plugin2", Reflect.on(PluginRemoteSync.PluginStatus.class).call("create","com.fr.plugin2","1",true).get()); +// put("com.fr.plugin3", Reflect.on(PluginRemoteSync.PluginStatus.class).call("create","com.fr.plugin3","1",false).get()); +// put("com.fr.plugin4", Reflect.on(PluginRemoteSync.PluginStatus.class).call("create","com.fr.plugin4","1",false).get()); +// }}).anyTimes(); +// EasyMock.replay(pluginRemoteSync); +// PowerMock.mockStaticPartial(PluginRemoteSync.class, "getInstance"); +// EasyMock.expect(PluginRemoteSync.getInstance()).andReturn(pluginRemoteSync).anyTimes(); +// PowerMock.replay(PluginRemoteSync.class); // 本地插件模拟检查 TemplateIOErrorContextHolder.registerPluginNameMap(new HashMap() {{ @@ -81,7 +76,7 @@ public class DesignerAppUtilsTest { put("com.fr.plugin3", "好用的插件3"); put("com.fr.plugin4", "好用的插件4"); put("com.fr.plugin5", "好用的插件5"); - }},new HashSet<>()); + }}, new HashSet<>()); // unknown TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("com.fr.plugin7", "1")); // disable @@ -93,14 +88,14 @@ public class DesignerAppUtilsTest { Multimap pendingPlugins = TemplateIOErrorContextHolder.getPendingPlugin(); - Reflect.on(DesignerAppUtils.class).call("rearrange",pendingPlugins).get(); - Assert.assertEquals(1,pendingPlugins.get(TemplateIOErrorContextHolder.UNKNOWN_PLUGIN).size()); + Reflect.on(DesignerAppUtils.class).call("rearrange", pendingPlugins).get(); + Assert.assertEquals(1, pendingPlugins.get(TemplateIOErrorContextHolder.UNKNOWN_PLUGIN).size()); Collection pluginMarkerAdapters = pendingPlugins.get(TemplateIOErrorContextHolder.DISABLE_PLUGIN); Assert.assertEquals(2, pluginMarkerAdapters.size()); pluginMarkerAdapters.contains(PluginMarker.create("com.fr.plugin3", "1")); pluginMarkerAdapters.contains(PluginMarker.create("com.fr.plugin4", "1")); Collection pluginMarkerAdapters1 = pendingPlugins.get(TemplateIOErrorContextHolder.NOT_INSTALLED_PLUGIN); Assert.assertEquals(1, pluginMarkerAdapters1.size()); - pluginMarkerAdapters1.contains(PluginMarker.create("com.fr.plugin5","1")); + pluginMarkerAdapters1.contains(PluginMarker.create("com.fr.plugin5", "1")); } } \ No newline at end of file