diff --git a/designer-base/src/main/java/com/fr/design/border/UIRoundedBorder.java b/designer-base/src/main/java/com/fr/design/border/UIRoundedBorder.java index 757bbbbe0..4530f0f48 100644 --- a/designer-base/src/main/java/com/fr/design/border/UIRoundedBorder.java +++ b/designer-base/src/main/java/com/fr/design/border/UIRoundedBorder.java @@ -1,32 +1,33 @@ package com.fr.design.border; import com.fr.base.GraphHelper; +import com.fr.stable.GraphDrawHelper; import javax.swing.border.LineBorder; -import java.awt.Color; -import java.awt.Component; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; +import java.awt.*; import java.awt.geom.RoundRectangle2D; public class UIRoundedBorder extends LineBorder { private static final long serialVersionUID = 1L; + private BasicStroke stroke4Thickness; private int roundedCorner; private int lineStyle; public UIRoundedBorder(Color color) { super(color); + this.stroke4Thickness = new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); } public UIRoundedBorder(Color color, int thickness){ super(color, thickness); + this.stroke4Thickness = new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); } public UIRoundedBorder(Color color, int thickness, int roundedCorners){ super(color, thickness, true); + this.stroke4Thickness = new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); this.roundedCorner = roundedCorners; } @@ -51,7 +52,19 @@ public class UIRoundedBorder extends LineBorder { Graphics2D g2d = (Graphics2D)g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(lineColor); - GraphHelper.draw(g2d, new RoundRectangle2D.Double(x, y, width - 1.0D, height - 1.0D, roundedCorner, roundedCorner), lineStyle); + + Shape shape = new RoundRectangle2D.Double(x, y, width - 1.0D, height - 1.0D, roundedCorner, roundedCorner); + + if (stroke4Thickness != null) { + Stroke oldStroke = g2d.getStroke(); + g2d.setStroke(stroke4Thickness); + g2d.draw(shape); + + g2d.setStroke(oldStroke); + } else { + GraphHelper.draw(g2d, shape, lineStyle); + } + g2d.setColor(oldColor); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java index 01af97293..58a021812 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java @@ -1,8 +1,9 @@ package com.fr.design.data.datapane.connect; +import com.fr.base.GraphHelper; import com.fr.data.impl.JDBCDatabaseConnection; import com.fr.data.pool.DBCPConnectionPoolAttr; -import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicPane; import com.fr.design.editor.editor.IntegerEditor; import com.fr.design.gui.icombobox.UIComboBox; @@ -12,14 +13,35 @@ import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; -import java.awt.BorderLayout; -import java.awt.Component; -import javax.swing.BorderFactory; +import com.fr.general.ComparatorUtils; +import com.fr.stable.StringUtils; + import javax.swing.JPanel; +import javax.swing.JTextField; import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Window; +import java.awt.event.InputMethodEvent; +import java.awt.event.InputMethodListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class DBCPAttrPane extends BasicPane { public static final int TIME_MULTIPLE = 1000; + private static final Pattern FETCHSIZE_PATTERN = Pattern.compile("^0$|^[1-9][\\d]*[\\d]*$");; + private static final Pattern CHAR_NEED_ESCAPE = Pattern.compile("[?|$^*\\\\\\[\\](){}.+]"); + private static final int MAX_FETCHSIZE = 1000000; + private static final Map DEFAULT_FETCHSIZE_MAP = new HashMap<>(); + private static final int ORACLE_DEFAULT_FETCHSIZE = 128; + private static final int DB2_DEFAULT_FETCHSIZE = 50; + private static final int POSTGRE_DEFAULT_FETCHSIZE = 10000; // carl:DBCP的一些属性 private IntegerEditor DBCP_INITIAL_SIZE = new IntegerEditor(); private IntegerEditor DBCP_MAX_ACTIVE = new IntegerEditor(); @@ -36,11 +58,24 @@ public class DBCPAttrPane extends BasicPane { private IntegerEditor DBCP_NUMTESTSPEREVICTIONRUN = new IntegerEditor(); private IntegerEditor DBCP_MINEVICTABLEIDLETIMEMILLIS = new IntegerEditor(); + private UITextField FETCHSIZE = new UITextField(); + + private JPanel defaultPane; + private JPanel northFlowPane; + private JPanel southFlowPane; + + static { + DEFAULT_FETCHSIZE_MAP.put("Oracle", ORACLE_DEFAULT_FETCHSIZE); + DEFAULT_FETCHSIZE_MAP.put("DB2", DB2_DEFAULT_FETCHSIZE); + DEFAULT_FETCHSIZE_MAP.put("Postgre", POSTGRE_DEFAULT_FETCHSIZE); + } + public DBCPAttrPane() { - JPanel defaultPane = this; + defaultPane = this; // JPanel northFlowPane - JPanel northFlowPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane(); + northFlowPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Basic_ConnectionPool_Attr")); + northFlowPane.setPreferredSize(new Dimension(630, 320)); defaultPane.add(northFlowPane, BorderLayout.NORTH); DBCP_VALIDATION_QUERY.setColumns(15); @@ -67,7 +102,6 @@ public class DBCPAttrPane extends BasicPane { DBCP_MINEVICTABLEIDLETIMEMILLIS}}; JPanel contextPane = TableLayoutHelper.createGapTableLayoutPane(comps, rowSize, columnSize, 10, 4); - contextPane.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, UIConstants.LINE_COLOR)); northFlowPane.add(contextPane); } @@ -89,6 +123,10 @@ public class DBCPAttrPane extends BasicPane { this.DBCP_MINEVICTABLEIDLETIMEMILLIS.setValue(dbcpAttr.getMinEvictableIdleTimeMillis() / TIME_MULTIPLE); this.DBCP_NUMTESTSPEREVICTIONRUN.setValue(dbcpAttr.getNumTestsPerEvictionRun()); this.DBCP_TIMEBETWEENEVICTIONRUNSMILLS.setValue(dbcpAttr.getTimeBetweenEvictionRunsMillis()); + Integer fetchSize = DEFAULT_FETCHSIZE_MAP.get(JDBCConnectionDef.getInstance().getDatabaseName()); + if (fetchSize != null) { + this.FETCHSIZE.setText(jdbcDatabase.getFetchSize() == -1 ? String.valueOf(fetchSize) : String.valueOf(jdbcDatabase.getFetchSize())); + } } public void update(JDBCDatabaseConnection jdbcDatabase) { @@ -109,10 +147,94 @@ public class DBCPAttrPane extends BasicPane { dbcpAttr.setMinEvictableIdleTimeMillis(((Number) this.DBCP_MINEVICTABLEIDLETIMEMILLIS.getValue()).intValue() * TIME_MULTIPLE); dbcpAttr.setNumTestsPerEvictionRun(((Number) this.DBCP_NUMTESTSPEREVICTIONRUN.getValue()).intValue()); dbcpAttr.setTimeBetweenEvictionRunsMillis(((Number) this.DBCP_TIMEBETWEENEVICTIONRUNSMILLS.getValue()).intValue()); + Integer fetchSize = DEFAULT_FETCHSIZE_MAP.get(JDBCConnectionDef.getInstance().getDatabaseName()); + if (fetchSize != null) { + jdbcDatabase.setFetchSize(Integer.parseInt(this.FETCHSIZE.getText())); + } + } + + @Override + public BasicDialog showWindow(Window window) { + String databaseName = JDBCConnectionDef.getInstance().getDatabaseName(); + if (showOtherConfig(databaseName)) { + southFlowPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Report_Other")); + southFlowPane.setPreferredSize(new Dimension(630, 200)); + double f = TableLayout.FILL; + double[] rowSize = {f}; + double otherColumnSize = GraphHelper.getWidth(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Evictionruns_millis")) + 6; + double[] columnSize = {otherColumnSize, otherColumnSize}; + FETCHSIZE.addKeyListener(fetchSizeKeyListener); + FETCHSIZE.addInputMethodListener(fetchSizeInputMethodListener); + FETCHSIZE.setHorizontalAlignment(JTextField.RIGHT); + Component[][] comps = { + {new UILabel("Fetchsize:", SwingConstants.RIGHT), FETCHSIZE} + }; + JPanel otherConfigPane = TableLayoutHelper.createGapTableLayoutPane(comps, rowSize, columnSize, 10, 4); + southFlowPane.add(otherConfigPane); + + defaultPane.removeAll(); + defaultPane.add(northFlowPane, BorderLayout.NORTH); + defaultPane.add(southFlowPane, BorderLayout.SOUTH); + } else { + if (southFlowPane != null) { + defaultPane.remove(southFlowPane); + } + } + return this.showWindow(window, null); + } + + private boolean showOtherConfig(Object dbType) { + return ComparatorUtils.equals(dbType, "Oracle") || ComparatorUtils.equals(dbType, "DB2") || ComparatorUtils.equals(dbType, "Postgre"); + } + + KeyListener fetchSizeKeyListener = new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + String fetchSize = FETCHSIZE.getText(); + if (!isFetchSizeValid(fetchSize)) { + FETCHSIZE.setText(fetchSize.replaceAll(getCharNeedReplace(e.getKeyChar()), "")); + if (!isFetchSizeValid(FETCHSIZE.getText())) { + FETCHSIZE.setText(StringUtils.EMPTY); + } + } else if (FETCHSIZE.getText().length() > String.valueOf(MAX_FETCHSIZE).length() || Long.parseLong(FETCHSIZE.getText()) > MAX_FETCHSIZE) { + FETCHSIZE.setText(String.valueOf(MAX_FETCHSIZE)); + } + } + }; + + InputMethodListener fetchSizeInputMethodListener = new InputMethodListener() { + @Override + public void inputMethodTextChanged(InputMethodEvent event) { + if (null == event.getText()) { + return; + } + char ch = event.getText().current(); + if (!(ch >= '0' && ch <= '9')) { + event.consume(); + } + } + + @Override + public void caretPositionChanged(InputMethodEvent event) { + + } + }; + + private boolean isFetchSizeValid(String fetchSize) { + return FETCHSIZE_PATTERN.matcher(fetchSize).find(); + } + + private String getCharNeedReplace(char c) { + String charNeedReplace = c + ""; + Matcher matcher = CHAR_NEED_ESCAPE.matcher(charNeedReplace); + if (matcher.find()) { + charNeedReplace = "\\" + charNeedReplace; + } + return charNeedReplace; } @Override protected String title4PopupWindow() { - return Toolkit.i18nText("Fine-Design_Basic_ConnectionPool_Attr"); + return Toolkit.i18nText("Fine-Design_Basic_Advanced_Setup"); } } 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 f3a97ffb1..e55aaa2dd 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 @@ -12,7 +12,6 @@ import com.fr.data.solution.entity.DriverPage; import com.fr.data.solution.processor.ClassNotFoundExceptionSolutionProcessor; import com.fr.data.solution.processor.SolutionProcessor; import com.fr.design.beans.BasicBeanPane; -import com.fr.design.dialog.BasicPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.ilable.ActionLabel; @@ -338,7 +337,7 @@ public abstract class DatabaseConnectionPane extends JComponent { // 约定图片的文件名为this.getName(),处理起来方便些 // b:这里国际化没有考虑 public Icon getIcon() { + if (StringUtils.isEmpty(this.getIconName())) { + return null; + } String iconName = "com/fr/design/images/buttonicon/" + this.getIconName() + ".png"; try { return BaseUtils.readIcon(iconName); diff --git a/designer-base/src/main/java/com/fr/design/file/Releasable.java b/designer-base/src/main/java/com/fr/design/file/Releasable.java deleted file mode 100644 index cb78789e6..000000000 --- a/designer-base/src/main/java/com/fr/design/file/Releasable.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.fr.design.file; - -public interface Releasable { - void releaseResources(); -} diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/UIPercentDragPane.java b/designer-base/src/main/java/com/fr/design/gui/frpane/UIPercentDragPane.java new file mode 100644 index 000000000..1dd96de00 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/UIPercentDragPane.java @@ -0,0 +1,30 @@ +package com.fr.design.gui.frpane; + +import com.fr.design.gui.ilable.UILabel; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Starryi + * @version 10.0.18 + * Created by Starryi on 2021/7/3 + */ +public class UIPercentDragPane extends JPanel { + + private final UINumberDragPane dragPane = new UINumberDragPane(0, 100, 1); + + public UIPercentDragPane() { + setLayout(new BorderLayout()); + add(dragPane, BorderLayout.CENTER); + add(new UILabel(" %"), BorderLayout.EAST); + } + + public void populateBean(double value) { + dragPane.populateBean(value * 100); + } + + public double updateBean() { + return dragPane.updateBean() * 100; + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/LineComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/LineComboBox.java index ca4eddfe3..65e24a7c3 100644 --- a/designer-base/src/main/java/com/fr/design/gui/icombobox/LineComboBox.java +++ b/designer-base/src/main/java/com/fr/design/gui/icombobox/LineComboBox.java @@ -3,22 +3,14 @@ */ package com.fr.design.gui.icombobox; -import com.fr.base.FRContext; import com.fr.base.GraphHelper; -import com.fr.base.ScreenResolution; -import com.fr.general.FRFont; import com.fr.stable.Constants; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Graphics2D; +import com.fr.stable.StringUtils; + +import javax.swing.*; +import java.awt.*; import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JLabel; -import javax.swing.JList; /** @@ -59,6 +51,13 @@ public class LineComboBox extends UIComboBox { this.setSelectedItem(new Integer(style)); } + protected String toStringFromStyle(int style) { + if (style == Constants.LINE_NONE) { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_None"); + } + return null; + } + /** * CellRenderer. */ @@ -67,31 +66,27 @@ public class LineComboBox extends UIComboBox { JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel comp= (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); this.style = ((Integer) value).intValue(); - comp.setText(null); + String displayString = toStringFromStyle(style); + if (StringUtils.isNotEmpty(displayString)) { + comp.setText(" " + displayString); + } else { + comp.setText(null); + } return comp; } public void paint(Graphics g) { super.paint(g); - Graphics2D g2d = (Graphics2D) g; - - Dimension d = getSize(); - g2d.setColor(getForeground()); - - FRFont font = FRContext.getDefaultValues().getFRFont(); - int resolution = ScreenResolution.getScreenResolution(); - Font rfont = font.applyResolutionNP(resolution); - g2d.setFont(rfont); - FontMetrics fm = GraphHelper.getFontMetrics(rfont); - if (style == Constants.LINE_NONE) { - //draw "none" string - GraphHelper.drawString(g2d, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_None"), 4, (d.height - fm.getHeight()) / 2D + fm.getAscent()); - } else { + if (StringUtils.isEmpty(toStringFromStyle(style))) { + Graphics2D g2d = (Graphics2D) g; + + Dimension d = getSize(); + g2d.setColor(getForeground()); GraphHelper.drawLine(g2d, 4, d.height / 2D, d.width - 8D, d.height / 2D, style); - } - - if(isShowAxisWithLineStyle()) { // 带有坐标轴箭头的样式. - drawArrow(g2d, new Point2D.Double(4, d.height / 2D), new Point2D.Double(d.width - 8D, d.height / 2D)); + + if(isShowAxisWithLineStyle()) { // 带有坐标轴箭头的样式. + drawArrow(g2d, new Point2D.Double(4, d.height / 2D), new Point2D.Double(d.width - 8D, d.height / 2D)); + } } } diff --git a/designer-base/src/main/java/com/fr/design/gui/ipasswordfield/UIPasswordFieldWithFixedLength.java b/designer-base/src/main/java/com/fr/design/gui/ipasswordfield/UIPasswordFieldWithFixedLength.java index c1cb98ca3..02ed99830 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ipasswordfield/UIPasswordFieldWithFixedLength.java +++ b/designer-base/src/main/java/com/fr/design/gui/ipasswordfield/UIPasswordFieldWithFixedLength.java @@ -68,7 +68,13 @@ public class UIPasswordFieldWithFixedLength extends UIPassWordField { this.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - UIPasswordFieldWithFixedLength.this.clearPassword = true; + UIPasswordFieldWithFixedLength.this.clearPassword = true; + } + + @Override + public void mousePressed(MouseEvent e) { + // 防止拖动进入 + UIPasswordFieldWithFixedLength.this.clearPassword = true; } }); this.addKeyListener(new KeyAdapter() { diff --git a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java index 454b1e5b9..9d10da3a7 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java +++ b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java @@ -58,6 +58,7 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver * Spinner内的数字文本框长度 */ private int numberFieldColumns; + private boolean hasTextFieldFocus = false; public UISpinner() { @@ -318,7 +319,7 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver @Override public void mouseWheelMoved(MouseWheelEvent e) { - if (isEnabled() && e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { + if (hasTextFieldFocus && isEnabled() && e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { setValue(value - e.getWheelRotation()); } } @@ -330,8 +331,14 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver textField.getDocument().removeDocumentListener(docListener); textField.getDocument().addDocumentListener(docListener); textField.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + hasTextFieldFocus = true; + } + @Override public void focusLost(FocusEvent e) { + hasTextFieldFocus = false; textField.getDocument().removeDocumentListener(docListener); textField.setValue(value); textField.getDocument().addDocumentListener(docListener); diff --git a/designer-base/src/main/java/com/fr/design/gui/style/BackgroundPane.java b/designer-base/src/main/java/com/fr/design/gui/style/BackgroundPane.java index 13dd9e3c9..bdf96f32e 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/BackgroundPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/style/BackgroundPane.java @@ -70,13 +70,13 @@ public class BackgroundPane extends AbstractBasicStylePane { double f = TableLayout.FILL; double p = TableLayout.PREFERRED; Component[][] components = new Component[][]{ - new Component[]{null, null}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Fill") + " ", SwingConstants.LEFT),typeComboBox}, - new Component[]{null, centerPane} + new Component[]{null}, + new Component[]{typeComboBox}, + new Component[]{centerPane} }; double[] rowSize = {p, p, p}; - double[] columnSize = {p,f}; - int[][] rowCount = {{1, 1},{1, 1},{1, 1}}; + double[] columnSize = {f}; + int[][] rowCount = {{1},{1},{1}}; JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.VGAP_LARGE, LayoutConstants.VGAP_MEDIUM); this.add(panel, BorderLayout.CENTER); diff --git a/designer-base/src/main/java/com/fr/design/gui/style/BackgroundSpecialPane.java b/designer-base/src/main/java/com/fr/design/gui/style/BackgroundSpecialPane.java index 7fa266423..ee05a8b59 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/BackgroundSpecialPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/style/BackgroundSpecialPane.java @@ -39,7 +39,7 @@ public class BackgroundSpecialPane extends BackgroundPane{ fireStateChanged(); } }); - GradientBackgroundQuickPane gradientPane = new GradientBackgroundQuickPane(); + GradientBackgroundQuickPane gradientPane = createGradientBackgroundQuickPane(); gradientPane.registerChangeListener(new UIObserverListener() { @Override public void doChange() { @@ -68,4 +68,9 @@ public class BackgroundSpecialPane extends BackgroundPane{ return kinds.toArray(new BackgroundQuickPane[kinds.size()]); } + + protected GradientBackgroundQuickPane createGradientBackgroundQuickPane() { + // 使用默认的150宽度构建渐变条 + return new GradientBackgroundQuickPane(); + } } diff --git a/designer-base/src/main/java/com/fr/design/locale/impl/BbsRegisterMark.java b/designer-base/src/main/java/com/fr/design/locale/impl/BbsRegisterMark.java index 6c97b1e6b..afe1c8eef 100644 --- a/designer-base/src/main/java/com/fr/design/locale/impl/BbsRegisterMark.java +++ b/designer-base/src/main/java/com/fr/design/locale/impl/BbsRegisterMark.java @@ -16,8 +16,8 @@ import java.util.Map; public class BbsRegisterMark implements LocaleMark { private final Map map = new HashMap<>(); - private static final String BBS_REGISTER_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.register", "http://id.fanruan.com/register/register.php?clueSource=activityfr"); - private static final String BBS_REGISTER_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.register", "http://id.fanruan.com/register/register.php?clueSource=activityfr"); + private static final String BBS_REGISTER_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.register", "https://id.fanruan.com/register/register.php?clueSource=activityfr"); + private static final String BBS_REGISTER_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.register", "https://id.fanruan.com/register/register.php?clueSource=activityfr"); private static final String BBS_REGISTER_EN = CloudCenter.getInstance().acquireUrlByKind("bbs.register.en_US", "https://id.fanruan.com/en/register/register.php"); private static final String BBS_REGISTER_KR = CloudCenter.getInstance().acquireUrlByKind("bbs.register.en_US", "https://id.fanruan.com/en/register/register.php"); private static final String BBS_REGISTER_JP = CloudCenter.getInstance().acquireUrlByKind("bbs.register.en_US", "https://id.fanruan.com/en/register/register.php"); diff --git a/designer-base/src/main/java/com/fr/design/locale/impl/BbsResetMark.java b/designer-base/src/main/java/com/fr/design/locale/impl/BbsResetMark.java index b44a4e691..27db28e41 100644 --- a/designer-base/src/main/java/com/fr/design/locale/impl/BbsResetMark.java +++ b/designer-base/src/main/java/com/fr/design/locale/impl/BbsResetMark.java @@ -16,8 +16,8 @@ import java.util.Map; public class BbsResetMark implements LocaleMark { private final Map map = new HashMap<>(); - private static final String BBS_RESET_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.reset", "http://id.fanruan.com/forget/forget.php?clue=activityfr"); - private static final String BBS_RESET_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.reset", "http://id.fanruan.com/forget/forget.php?clue=activityfr"); + private static final String BBS_RESET_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.reset", "https://id.fanruan.com/forget/forget.php?clue=activityfr"); + private static final String BBS_RESET_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.reset", "https://id.fanruan.com/forget/forget.php?clue=activityfr"); private static final String BBS_RESET_EN = CloudCenter.getInstance().acquireUrlByKind("bbs.reset.en_US", "https://id.fanruan.com/en/forget/forget.php"); private static final String BBS_RESET_KR = CloudCenter.getInstance().acquireUrlByKind("bbs.reset.en_US", "https://id.fanruan.com/en/forget/forget.php"); private static final String BBS_RESET_JP = CloudCenter.getInstance().acquireUrlByKind("bbs.reset.en_US", "https://id.fanruan.com/en/forget/forget.php"); diff --git a/designer-base/src/main/java/com/fr/design/login/AbstractDesignerSSO.java b/designer-base/src/main/java/com/fr/design/login/AbstractDesignerSSO.java index 6fc3c817b..2662198bb 100644 --- a/designer-base/src/main/java/com/fr/design/login/AbstractDesignerSSO.java +++ b/designer-base/src/main/java/com/fr/design/login/AbstractDesignerSSO.java @@ -20,6 +20,10 @@ public abstract class AbstractDesignerSSO extends UpdateAction { @Override public void actionPerformed(ActionEvent event) { String url = getJumpUrl(); + if (!DesignerLoginUtils.isOnline()) { + BrowseUtils.browser(url); + return; + } DesignerEnvManager manager = DesignerEnvManager.getEnvManager(); int uid = manager.getDesignerLoginUid(); if (uid > 0) { diff --git a/designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java b/designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java index 8adebba4f..92e417146 100644 --- a/designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java +++ b/designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java @@ -4,9 +4,13 @@ import com.fr.base.FRContext; import com.fr.design.DesignerEnvManager; import com.fr.design.dialog.UIDialog; import com.fr.design.event.DesignerOpenedListener; +import com.fr.design.login.utils.DesignerLoginUtils; import com.fr.design.mainframe.DesignerContext; import com.fr.design.os.impl.SupportOSImpl; import com.fr.design.update.push.DesignerPushUpdateManager; +import com.fr.general.CloudCenter; +import com.fr.general.CloudCenterConfig; +import com.fr.general.http.HttpToolbox; import com.fr.stable.StringUtils; import javax.swing.WindowConstants; @@ -35,7 +39,7 @@ public class DesignerGuideHelper { public static void prepareShowGuideDialog() { // 如果存在更新升级的弹窗,则不显示引导页面 - if (!SupportOSImpl.DESIGNER_LOGIN.support() || !FRContext.isChineseEnv() || DesignerPushUpdateManager.getInstance().isShouldPopUp()) { + if (!DesignerLoginUtils.isOnline() || !SupportOSImpl.DESIGNER_LOGIN.support() || !FRContext.isChineseEnv() || DesignerPushUpdateManager.getInstance().isShouldPopUp()) { return; } if (isActivatedForOneWeek()) { diff --git a/designer-base/src/main/java/com/fr/design/login/message/DesignerMessageHelper.java b/designer-base/src/main/java/com/fr/design/login/message/DesignerMessageHelper.java index c053fc0e5..f3768629b 100644 --- a/designer-base/src/main/java/com/fr/design/login/message/DesignerMessageHelper.java +++ b/designer-base/src/main/java/com/fr/design/login/message/DesignerMessageHelper.java @@ -51,6 +51,9 @@ public class DesignerMessageHelper { } public void prepareShowMessage() { + if (!DesignerLoginUtils.isOnline()) { + return; + } DesignerContext.getDesignerFrame().addDesignerOpenedListener(new DesignerOpenedListener() { @Override public void designerOpened() { diff --git a/designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java b/designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java index 26e095df6..a39a0be4b 100644 --- a/designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java +++ b/designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java @@ -3,10 +3,13 @@ package com.fr.design.login.utils; import com.fr.design.DesignerEnvManager; import com.fr.design.mainframe.toast.DesignerToastMsgUtil; import com.fr.general.CloudCenter; +import com.fr.general.CloudCenterConfig; import com.fr.general.GeneralContext; +import com.fr.general.http.HttpToolbox; import com.fr.general.log.MessageFormatter; import com.fr.json.JSONObject; import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; import com.fr.third.org.bouncycastle.util.encoders.Hex; import java.awt.Window; import java.security.SecureRandom; @@ -49,6 +52,9 @@ public class DesignerLoginUtils { } public static String generateDesignerSSOUrl(String referrer) { + if (!DesignerLoginUtils.isOnline()) { + return referrer; + } String ssoTemplate = CloudCenter.getInstance().acquireUrlByKind("designer.sso.api", "https://id.fanruan.com/api/app/?code={}&referrer={}"); try { String code = generateLoginCode(); @@ -60,6 +66,19 @@ public class DesignerLoginUtils { return referrer; } + public static boolean isOnline() { + if (CloudCenterConfig.getInstance().isOnline()) { + String ping = CloudCenter.getInstance().acquireConf("ping", StringUtils.EMPTY); + if (StringUtils.isNotEmpty(ping)) { + try { + return StringUtils.isEmpty(HttpToolbox.get(ping)); + } catch (Exception ignore) { + } + } + } + return false; + } + private static String generateLoginCode() throws Exception { DesignerEnvManager manager = DesignerEnvManager.getEnvManager(); JSONObject jo = JSONObject.create(); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java index 3cc4fba62..e5c18d097 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java @@ -55,6 +55,9 @@ import com.fr.start.OemHandler; import com.fr.workspace.WorkContext; import com.fr.workspace.Workspace; import com.fr.workspace.connect.WorkspaceConnectionInfo; +import java.util.HashMap; +import java.util.Map; +import org.jetbrains.annotations.Nullable; import javax.swing.Icon; import javax.swing.JComponent; @@ -137,6 +140,8 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta private int contentHeight = (int) (java.awt.Toolkit.getDefaultToolkit().getScreenSize().getHeight()); + private Map map = new HashMap<>(); + private WindowAdapter windowAdapter = new WindowAdapter() { @Override @@ -396,6 +401,21 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta } } + @Override + public synchronized void addWindowListener(WindowListener l) { + SafeWindowListener safeWindowListener = new SafeWindowListener(l); + map.put(l, safeWindowListener); + super.addWindowListener(safeWindowListener); + } + + @Override + public synchronized void removeWindowListener(WindowListener l) { + SafeWindowListener safeWindowListener = map.remove(l); + if (safeWindowListener != null) { + super.removeWindowListener(safeWindowListener); + } + } + private void addMacOsListener() { OSSupportCenter.buildAction(new MacOsAddListenerAction(), SupportOSImpl.DOCK_QUIT); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/OpenLoadingPane.java b/designer-base/src/main/java/com/fr/design/mainframe/OpenLoadingPane.java index 624f280a7..adc30b2bf 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/OpenLoadingPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/OpenLoadingPane.java @@ -1,6 +1,7 @@ package com.fr.design.mainframe; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; import com.fr.general.IOUtils; import java.awt.Color; import java.awt.Component; @@ -17,9 +18,13 @@ import javax.swing.JPanel; */ public class OpenLoadingPane extends JPanel { - private static final ImageIcon LOADING_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/mainframe/loading.gif")); + private static final ImageIcon LOADING_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/mainframe/openloading.png")); + private static final Color TIP_COLOR = new Color(108, 174, 235); + private static final int Y_GAP = 50; + private static final int X_GAP = 10; private UILabel loadingLabel; + private UILabel tipLabel; public OpenLoadingPane() { @@ -47,7 +52,12 @@ public class OpenLoadingPane extends JPanel { int loadingLabelHeight = loadingLabel.getPreferredSize().height; int loadingLabelX = (width - loadingLabelWidth) / 2; int loadingLabelY = (height - loadingLabelHeight) / 2; + int tipLabelWidth = tipLabel.getPreferredSize().width; + int tipLabelHeight = tipLabel.getPreferredSize().height; + int tipLabelX = (width - tipLabelWidth) / 2 + X_GAP; + int tipLabelY = loadingLabelY + loadingLabelHeight - Y_GAP; loadingLabel.setBounds(loadingLabelX, loadingLabelY, loadingLabelWidth, loadingLabelHeight); + tipLabel.setBounds(tipLabelX, tipLabelY, tipLabelWidth, tipLabelHeight); } @Override @@ -56,7 +66,10 @@ public class OpenLoadingPane extends JPanel { }); setBackground(Color.WHITE); loadingLabel = new UILabel(LOADING_ICON); + tipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Open_Template_Loading")); + tipLabel.setForeground(TIP_COLOR); add(loadingLabel); + add(tipLabel); } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/SafeWindowListener.java b/designer-base/src/main/java/com/fr/design/mainframe/SafeWindowListener.java new file mode 100644 index 000000000..d88eccfa7 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/SafeWindowListener.java @@ -0,0 +1,84 @@ +package com.fr.design.mainframe; + +import com.fr.log.FineLoggerFactory; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; + +/** + * 保证监听运行出错也不影响其他功能正常使用 + * + * @author hades + * @version 10.0 + * Created by hades on 2021/6/30 + */ +public class SafeWindowListener implements WindowListener { + + private final WindowListener windowListener; + + public SafeWindowListener(WindowListener windowListener) { + this.windowListener = windowListener; + } + + @Override + public void windowOpened(WindowEvent e) { + try { + windowListener.windowOpened(e); + } catch (Throwable throwable) { + FineLoggerFactory.getLogger().debug(throwable.getMessage(), throwable); + } + } + + @Override + public void windowClosing(WindowEvent e) { + try { + windowListener.windowClosing(e); + } catch (Throwable throwable) { + FineLoggerFactory.getLogger().debug(throwable.getMessage(), throwable); + } + } + + @Override + public void windowClosed(WindowEvent e) { + try { + windowListener.windowClosed(e); + } catch (Throwable throwable) { + FineLoggerFactory.getLogger().debug(throwable.getMessage(), throwable); + } + } + + @Override + public void windowIconified(WindowEvent e) { + try { + windowListener.windowIconified(e); + } catch (Throwable throwable) { + FineLoggerFactory.getLogger().debug(throwable.getMessage(), throwable); + } + } + + @Override + public void windowDeiconified(WindowEvent e) { + try { + windowListener.windowDeiconified(e); + } catch (Throwable throwable) { + FineLoggerFactory.getLogger().debug(throwable.getMessage(), throwable); + } + } + + @Override + public void windowActivated(WindowEvent e) { + try { + windowListener.windowActivated(e); + } catch (Throwable throwable) { + FineLoggerFactory.getLogger().debug(throwable.getMessage(), throwable); + } + } + + @Override + public void windowDeactivated(WindowEvent e) { + try { + windowListener.windowDeactivated(e); + } catch (Throwable throwable) { + FineLoggerFactory.getLogger().debug(throwable.getMessage(), throwable); + } + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/backgroundpane/ImagePreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/backgroundpane/ImagePreviewPane.java index 24b3ebfc4..10629de02 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/backgroundpane/ImagePreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/backgroundpane/ImagePreviewPane.java @@ -52,8 +52,15 @@ public class ImagePreviewPane extends JComponent implements Scrollable, ImagePre private boolean isLoading = false; public ImagePreviewPane() { - sizeLabel = new UILabel(); - this.add(sizeLabel); + this(true); + } + + public ImagePreviewPane(boolean showSizeLabel) { + if (showSizeLabel) { + sizeLabel = new UILabel(); + this.add(sizeLabel); + } + this.setBorder(BorderFactory.createEmptyBorder(10, 10, 20, 10)); this.setLayout(new BorderLayout()); this.add(new JPanel() { @@ -117,7 +124,9 @@ public class ImagePreviewPane extends JComponent implements Scrollable, ImagePre ((JViewport) this.getParent()).setMinimumSize(newDimension); ((JViewport) this.getParent()).setMaximumSize(newDimension); } - sizeLabel.setText(null); + if (sizeLabel != null) { + sizeLabel.setText(null); + } } else { isLoading = false; // wait for the size of image. @@ -128,10 +137,14 @@ public class ImagePreviewPane extends JComponent implements Scrollable, ImagePre int totalwidth = ImagePreviewPane.this.getWidth(); int totalheight = ImagePreviewPane.this.getHeight(); String text = imageWidth + "x" + imageHeight; - sizeLabel.setText(text); + if (sizeLabel != null) { + sizeLabel.setText(text); + } FontMetrics cellFM = this.getFontMetrics(getFont()); int width = cellFM.stringWidth(text); - sizeLabel.setBounds(totalwidth - width - LABEL_DELTA_X, totalheight - LABEL_DELTA_Y, width, LABEL_HEIGHT); + if (sizeLabel != null) { + sizeLabel.setBounds(totalwidth - width - LABEL_DELTA_X, totalheight - LABEL_DELTA_Y, width, LABEL_HEIGHT); + } } fireChangeListener(); this.revalidate(); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/form/FormECDesignerProvider.java b/designer-base/src/main/java/com/fr/design/mainframe/form/FormECDesignerProvider.java index 27b4a249a..88a462307 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/form/FormECDesignerProvider.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/form/FormECDesignerProvider.java @@ -90,4 +90,6 @@ public interface FormECDesignerProvider { BufferedImage getElementCaseImage(Dimension elementCaseContainerSize); void refreshPropertyPane(); + + void removeSelection(); } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java b/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java index e63395ff6..045d54413 100644 --- a/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java +++ b/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java @@ -39,6 +39,7 @@ import java.lang.reflect.Method; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -59,6 +60,21 @@ public class VersionCheckUtils { private static final String ID = "id"; private static final String VERSION = "version"; private static final String NAME = "name"; + private static final Set pluginsNeedIgnore = new HashSet<>(); + static { + pluginsNeedIgnore.addAll(Arrays.asList( + "com.fr.plugin.performance.newexecutetool", + "com.fr.plugin.performance.newline", + "com.fr.plugin.performance.pdfstream", + "com.fr.plugin.performance.dzstartemptyfile", + "com.fr.plugin.performance.treenode.button.optimization", + "com.fr.plugin.performance.druid", + "com.fr.plugin.performance.reducecalculation", + "com.fr.plugin.performance.fasttree", + "com.fr.plugin.performance.paralleldsloader", + "com.fr.plugin.cloud.analytics.v10" + )); + } public static boolean versionCheck(String envName) { @@ -236,6 +252,9 @@ public class VersionCheckUtils { continue; } String remotePluginID = remotePlugin.getString(ID); + if (pluginsNeedIgnore.contains(remotePluginID)) { + continue; + } if (localPluginsMap.containsKey(remotePluginID)) { if (ComparatorUtils.equals(localPluginsMap.get(remotePluginID).getVersion(), remotePlugin.getString(VERSION))) { continue; diff --git a/designer-base/src/main/java/com/fr/design/widget/WidgetBoundsPaneFactory.java b/designer-base/src/main/java/com/fr/design/widget/WidgetBoundsPaneFactory.java index 9b6e7b5c8..ae3dfc255 100644 --- a/designer-base/src/main/java/com/fr/design/widget/WidgetBoundsPaneFactory.java +++ b/designer-base/src/main/java/com/fr/design/widget/WidgetBoundsPaneFactory.java @@ -10,6 +10,7 @@ import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import javax.swing.BorderFactory; +import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.SwingConstants; import java.awt.BorderLayout; @@ -45,23 +46,28 @@ public class WidgetBoundsPaneFactory { private static final int RIGHT_PANE_WIDTH = 145; - public static UIExpandablePane createBoundsPane(UISpinner width, UISpinner height) { + public static UIExpandablePane createBoundsPane(UISpinner width, UISpinner height, JComponent ratioLocked) { JPanel boundsPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); double f = TableLayout.FILL; double p = TableLayout.PREFERRED; Component[][] components = new Component[][]{ - new Component[]{FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Basic_Component_Size")), createRightPane(width, height)}, + new Component[]{FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Basic_Component_Size")), + ratioLocked != null ? createRightPane(width, ratioLocked, height) : createRightPane(width, height)}, new Component[]{null, createRightPane(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Tree_Width"), SwingConstants.CENTER), new UILabel(Toolkit.i18nText("Fine-Design_Basic_Tree_Height"), SwingConstants.CENTER))}, }; double[] rowSize = {p, p}; double[] columnSize = {f, RIGHT_PANE_WIDTH}; - int[][] rowCount = {{1, 1}, {1, 1}}; + int[][] rowCount = ratioLocked != null ? new int[][]{{1, 1}, {1, 1, 1}} : new int[][]{{1, 1}, {1, 1}}; final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W5, IntervalConstants.INTERVAL_L6); panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); boundsPane.add(panel); return new UIExpandablePane(Toolkit.i18nText("Fine-Design_Form_Coords_And_Size"), 280, 24, boundsPane); } + public static UIExpandablePane createBoundsPane(UISpinner width, UISpinner height) { + return createBoundsPane(width, height, null); + } + public static JPanel createRightPane(Component com1, Component com2) { double f = TableLayout.FILL; double p = TableLayout.PREFERRED; @@ -74,21 +80,41 @@ public class WidgetBoundsPaneFactory { return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_L6, IntervalConstants.INTERVAL_L1); } - public static UIExpandablePane createAbsoluteBoundsPane(UISpinner x, UISpinner y, UISpinner width, UISpinner height, NameAttribute nameAttribute) { + public static JPanel createRightPane(Component com1, Component com2, Component com3) { + double f = TableLayout.FILL; + double p = TableLayout.PREFERRED; + double[] rowSize = {p}; + double[] columnSize = {f, 24, f}; + int[][] rowCount = {{1, 1, 1}}; + Component[][] components = new Component[][]{ + new Component[]{com1, com2, com3} + }; + return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 0, IntervalConstants.INTERVAL_L1); + } + + public static UIExpandablePane createAbsoluteBoundsPane(UISpinner x, UISpinner y, UISpinner width, UISpinner height, JComponent ratioLocked, NameAttribute nameAttribute) { double f = TableLayout.FILL; double p = TableLayout.PREFERRED; + UILabel positionLabel = FRWidgetFactory.createLineWrapLabel(nameAttribute.getPositionName()); + UILabel xLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_X_Coordinate"), SwingConstants.CENTER); + UILabel yLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Y_Coordinate"), SwingConstants.CENTER); + + UILabel sizeLabel = FRWidgetFactory.createLineWrapLabel(nameAttribute.getSizeName()); + UILabel widthLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Tree_Width"), SwingConstants.CENTER); + UILabel heightLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Tree_Height"), SwingConstants.CENTER); + Component[][] northComponents = new Component[][]{ - new Component[]{FRWidgetFactory.createLineWrapLabel(nameAttribute.getPositionName()), createRightPane(x, y)}, - new Component[]{null, createRightPane(new UILabel(Toolkit.i18nText("Fine-Design_Basic_X_Coordinate"), SwingConstants.CENTER), new UILabel(Toolkit.i18nText("Fine-Design_Basic_Y_Coordinate"), SwingConstants.CENTER))}, + new Component[]{positionLabel, ratioLocked != null ? createRightPane(x, null, y) : createRightPane(x, y)}, + new Component[]{null, ratioLocked != null ? createRightPane(xLabel, null, yLabel) : createRightPane(xLabel, yLabel)}, }; Component[][] centerComponents = new Component[][]{ - new Component[]{FRWidgetFactory.createLineWrapLabel(nameAttribute.getSizeName()), createRightPane(width, height)}, - new Component[]{null, createRightPane(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Tree_Width"), SwingConstants.CENTER), new UILabel(Toolkit.i18nText("Fine-Design_Basic_Tree_Height"), SwingConstants.CENTER))}, + new Component[]{sizeLabel, ratioLocked != null ? createRightPane(width, ratioLocked, height) : createRightPane(width, height)}, + new Component[]{null, ratioLocked != null ? createRightPane(widthLabel, null, heightLabel) : createRightPane(widthLabel, heightLabel)}, }; double[] rowSize = {p, p}; double[] columnSize = {f, RIGHT_PANE_WIDTH}; - int[][] rowCount = {{1, 1}, {1, 1}}; + int[][] rowCount = ratioLocked != null ? new int[][]{{1, 1, 1}, {1, 1, 1}} : new int[][]{{1, 1}, {1, 1}}; final JPanel northPanel = TableLayoutHelper.createGapTableLayoutPane(northComponents, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W5, IntervalConstants.INTERVAL_L6); final JPanel centerPanel = TableLayoutHelper.createGapTableLayoutPane(centerComponents, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W5, IntervalConstants.INTERVAL_L6); JPanel boundsPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); @@ -99,6 +125,10 @@ public class WidgetBoundsPaneFactory { return new UIExpandablePane(Toolkit.i18nText("Fine-Design_Form_Coords_And_Size"), 230, 24, boundsPane); } + public static UIExpandablePane createAbsoluteBoundsPane(UISpinner x, UISpinner y, UISpinner width, UISpinner height, NameAttribute nameAttribute) { + return createAbsoluteBoundsPane(x, y, width, height, null, nameAttribute); + } + public static UIExpandablePane createAbsoluteBoundsPane(UISpinner x, UISpinner y, UISpinner width, UISpinner height) { return createAbsoluteBoundsPane(x, y, width, height, NameAttribute.DEFAULT); } diff --git a/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java b/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java index ef4b0e032..441a1fdec 100644 --- a/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java +++ b/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java @@ -168,7 +168,7 @@ public class CheckServiceDialog extends JDialog implements ActionListener { JPanel buttonPanel = FRGUIPaneFactory.createBorderLayout_M_Pane(); buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); boolean Sync = false; - if (Sync && isOnline()) { + if (isOnline() && Sync) { ignoreButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Sync_Ignore")); ignoreButton.addActionListener(this); syncButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Sync_To_Local")); @@ -308,6 +308,7 @@ public class CheckServiceDialog extends JDialog implements ActionListener { @Override public void mouseClicked(MouseEvent e) { ignoreButton.setEnabled(false); + syncButton.setEnabled(false); String[] option = {Toolkit.i18nText("Fine-Design_Report_Yes"), Toolkit.i18nText("Fine-Design_Report_No")}; if (!jarConsistency) { int a = FineJOptionPane.showOptionDialog(getParent(), Toolkit.i18nText("Fine-Design_Basic_Sync_Info_Information"), @@ -349,6 +350,7 @@ public class CheckServiceDialog extends JDialog implements ActionListener { @Override protected JSONArray doInBackground() { + progressBar.setVisible(true); progressBar.setString(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugins")); progressBar.setValue(0); return VersionCheckUtils.syncPlugins(differentPlugins); diff --git a/designer-base/src/main/java/com/fr/env/RemoteEnvPane.java b/designer-base/src/main/java/com/fr/env/RemoteEnvPane.java index 5be56bfbf..ab7f27df0 100644 --- a/designer-base/src/main/java/com/fr/env/RemoteEnvPane.java +++ b/designer-base/src/main/java/com/fr/env/RemoteEnvPane.java @@ -15,6 +15,7 @@ import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ipasswordfield.UIPassWordField; import com.fr.design.gui.ipasswordfield.UIPasswordFieldWithFixedLength; import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.DesignSizeI18nManager; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; @@ -653,7 +654,7 @@ public class RemoteEnvPane extends BasicBeanPane { dialog = new JDialog((Dialog) SwingUtilities.getWindowAncestor(RemoteEnvPane.this), Toolkit.i18nText("Fine-Design_Basic_Dialog_Message_Title"), true); - dialog.setSize(new Dimension(308, 132)); + dialog.setSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.env.RemoteEnvPane.dialog")); okButton.setEnabled(false); JPanel jp = new JPanel(); JPanel upPane = new JPanel(); diff --git a/designer-base/src/main/java/com/fr/env/utils/DesignerInteractionHistory.java b/designer-base/src/main/java/com/fr/env/utils/DesignerInteractionHistory.java new file mode 100644 index 000000000..45cebca48 --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/utils/DesignerInteractionHistory.java @@ -0,0 +1,148 @@ +package com.fr.env.utils; + +import com.fr.common.annotations.Compatible; +import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.EncodeConstants; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLReadable; +import com.fr.stable.xml.XMLTools; +import com.fr.stable.xml.XMLWriter; +import com.fr.stable.xml.XMLableReader; +import com.fr.third.javax.xml.stream.XMLStreamException; + +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; + +/** + * @author Starryi + * @version 10.0.18 + * Created by Starryi on 2021/7/7 + * 设计器访问和获取关键历史交互信息的持久化工具,该关键历史交互信息, + * 如用户是否点击过某按钮,是否查看过某弹窗信息,上次选择过的文件所在目录等 + */ +@Compatible +public class DesignerInteractionHistory implements XMLReadable, XMLWriter { + + private static final String FILE_NAME = "designer.ix.history.info"; + private static final String ROOT_TAG = "History"; + + private static DesignerInteractionHistory history; + public static DesignerInteractionHistory getInstance() { + if (history == null) { + history = new DesignerInteractionHistory(); + + readXMLFile(history, history.getHistoryFile()); + } + + return history; + } + + private File getHistoryFile() { + return new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), FILE_NAME)); + } + + private static void readXMLFile(XMLReadable xmlReadable, File xmlFile) { + if (xmlFile == null || !xmlFile.exists()) { + return; + } + String charset = EncodeConstants.ENCODING_UTF_8; + try { + String decodeContent = getFileContent(xmlFile); + InputStream xmlInputStream = new ByteArrayInputStream(decodeContent.getBytes(charset)); + InputStreamReader inputStreamReader = new InputStreamReader(xmlInputStream, charset); + + XMLableReader xmlReader = XMLableReader.createXMLableReader(inputStreamReader); + + if (xmlReader != null) { + xmlReader.readXMLObject(xmlReadable); + } + xmlInputStream.close(); + } catch (IOException | XMLStreamException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + + } + + private static String getFileContent(File xmlFile) throws FileNotFoundException, UnsupportedEncodingException { + InputStream encodeInputStream = new FileInputStream(xmlFile); + return IOUtils.inputStream2String(encodeInputStream); + } + + private static void writeContentToFile(String fileContent, File file) { + try (FileOutputStream fos = new FileOutputStream(file); + OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8); + BufferedWriter bw = new BufferedWriter(osw)) { + bw.write(fileContent); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + public void saveXMLFile() { + File xmlFile = this.getHistoryFile(); + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + XMLTools.writeOutputStreamXML(this, out); + out.flush(); + out.close(); + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + writeContentToFile(fileContent, xmlFile); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + + private static final String HAS_SHOWN_SHIFT_DRAG_RESIZING_TOOLTIP = "hasShownShiftDragResizingTooltip"; + private static final String LAST_SELECTED_BORDER_IMAGE_DIR = "lastSelectedBorderImageDir"; + + // 是否已展示过按下Shift键可锁定比例拖拽尺寸的Tooltip + private boolean hasShownShiftDragResizingTooltip = false; + // 用户上次通过文件选择器选择的边框图片所在目录 + private String lastSelectedBorderImageDir = StringUtils.EMPTY; + + public boolean isHasShownShiftDragResizingTooltip() { + return hasShownShiftDragResizingTooltip; + } + + public void setHasShownShiftDragResizingTooltip(boolean shown) { + this.hasShownShiftDragResizingTooltip = shown; + } + + public String getLastSelectedBorderImageDir() { + return lastSelectedBorderImageDir; + } + + public void setLastSelectedBorderImageDir(String dirPath) { + this.lastSelectedBorderImageDir = dirPath; + } + + @Override + public void writeXML(XMLPrintWriter writer) { + writer.startTAG(ROOT_TAG) + .attr(HAS_SHOWN_SHIFT_DRAG_RESIZING_TOOLTIP, isHasShownShiftDragResizingTooltip()) + .attr(LAST_SELECTED_BORDER_IMAGE_DIR, getLastSelectedBorderImageDir()) + .end(); + } + + @Override + public void readXML(XMLableReader reader) { + setHasShownShiftDragResizingTooltip(reader.getAttrAsBoolean(HAS_SHOWN_SHIFT_DRAG_RESIZING_TOOLTIP, false)); + setLastSelectedBorderImageDir(reader.getAttrAsString(LAST_SELECTED_BORDER_IMAGE_DIR, StringUtils.EMPTY)); + } +} 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 5fa8173d4..854d260bf 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 @@ -6,6 +6,7 @@ import com.fr.module.Activator; import com.fr.module.ModuleRole; import com.fr.stable.EncodeConstants; import com.fr.stable.ProductConstants; +import com.fr.stable.StringUtils; import com.fr.startup.FineWebApplicationInitializer; import com.fr.third.springframework.web.SpringServletContainerInitializer; import com.fr.third.springframework.web.context.support.AnnotationConfigWebApplicationContext; @@ -26,6 +27,8 @@ import java.util.Set; */ public class FineEmbedServerActivator extends Activator { + private static final String TOMCAT_MAX_HEADER_SIZE = "tomcat-maxHttpHeaderSize"; + private Tomcat tomcat; @Override @@ -68,6 +71,7 @@ public class FineEmbedServerActivator extends Activator { // 8.5.x 请求参数带特殊字符被tomcat拒绝 []|{}^\`"<> tomcat.getConnector().setProperty("relaxedQueryChars", "[]|{}^\`"<>"); setMaxPostSize(); + setMaxHttpHeaderSize(); String docBase = new File(WorkContext.getCurrent().getPath()).getParent(); //内置的上下文使用工程目录比如webroot @@ -102,6 +106,17 @@ public class FineEmbedServerActivator extends Activator { } } + private void setMaxHttpHeaderSize() { + String value = System.getProperty(TOMCAT_MAX_HEADER_SIZE); + if (StringUtils.isNotEmpty(value)) { + try { + tomcat.getConnector().setProperty("maxHttpHeaderSize", value); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } + private void stopServerActivator() { diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties index 23abf1ba4..6a227a996 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties @@ -3,3 +3,4 @@ com.fr.design.mainframe.check.CheckFontInfoDialog.collapse=630*185 com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink=630*31 com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=630*280 com.fr.design.report.ReportColumnsPane=800*600 +com.fr.env.RemoteEnvPane.dialog=458*132 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties index 97c7a38b6..db3632a29 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties @@ -1,4 +1,5 @@ com.fr.design.mainframe.check.CheckButton=280*118 com.fr.design.mainframe.check.CheckFontInfoDialog.collapse=610*185 com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink=610*31 -com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=610*280 \ No newline at end of file +com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=610*280 +com.fr.env.RemoteEnvPane.dialog=458*132 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties index c00c5eb62..b9d7ef15a 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties @@ -1,4 +1,5 @@ com.fr.design.mainframe.check.CheckButton=230*118 com.fr.design.mainframe.check.CheckFontInfoDialog.collapse=490*185 com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink=490*35 -com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=490*280 \ No newline at end of file +com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=490*280 +com.fr.env.RemoteEnvPane.dialog=458*132 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties index 85eb5c552..818a9d5d6 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties @@ -2,4 +2,5 @@ com.fr.design.mainframe.check.CheckButton=250*118 com.fr.design.mainframe.check.CheckFontInfoDialog.collapse=385*185 com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink=385*31 -com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=385*280 \ No newline at end of file +com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=385*280 +com.fr.env.RemoteEnvPane.dialog=308*132 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties index d6bdbbc64..87d117140 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties @@ -1,4 +1,5 @@ com.fr.design.mainframe.check.CheckButton=250*118 com.fr.design.mainframe.check.CheckFontInfoDialog.collapse=385*185 com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink=385*31 -com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=385*280 \ No newline at end of file +com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=385*280 +com.fr.env.RemoteEnvPane.dialog=308*132 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_border_image_help.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_border_image_help.png new file mode 100644 index 000000000..89a12190b Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_border_image_help.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_choose_inset.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_choose_inset.png new file mode 100644 index 000000000..18b39efd1 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_choose_inset.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_delete_inset.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_delete_inset.png new file mode 100644 index 000000000..3730383ee Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_delete_inset.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_both_selected.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_both_selected.png new file mode 100644 index 000000000..018fa1257 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_both_selected.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_both_unselected.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_both_unselected.png new file mode 100644 index 000000000..3a822ba8b Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_both_unselected.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_left_selected.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_left_selected.png new file mode 100644 index 000000000..b34a28704 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_left_selected.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_left_unselected.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_left_unselected.png new file mode 100644 index 000000000..7e8696b97 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_left_unselected.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_right_selected.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_right_selected.png new file mode 100644 index 000000000..d50ee4a07 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_right_selected.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_right_unselected.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_right_unselected.png new file mode 100644 index 000000000..d62026a7a Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_inset_right_unselected.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_lock_disabled.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_lock_disabled.png new file mode 100644 index 000000000..b498e7c14 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_lock_disabled.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_lock_enabled.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_lock_enabled.png new file mode 100644 index 000000000..38301e14d Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_lock_enabled.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_unlock_disabled.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_unlock_disabled.png new file mode 100644 index 000000000..6785a5130 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_unlock_disabled.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_unlock_enabled.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_unlock_enabled.png new file mode 100644 index 000000000..5d2582d80 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_unlock_enabled.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/edit_lock.png b/designer-base/src/main/resources/com/fr/design/images/control/edit_lock.png new file mode 100644 index 000000000..6168d9a98 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/edit_lock.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/edit_unlock.png b/designer-base/src/main/resources/com/fr/design/images/control/edit_unlock.png new file mode 100644 index 000000000..fae22d26d Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/edit_unlock.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/show_edit.png b/designer-base/src/main/resources/com/fr/design/images/control/show_edit.png new file mode 100644 index 000000000..9378e76c5 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/show_edit.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/show_setting.png b/designer-base/src/main/resources/com/fr/design/images/control/show_setting.png new file mode 100644 index 000000000..31da14c2e Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/show_setting.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/mainframe/openloading.png b/designer-base/src/main/resources/com/fr/design/images/mainframe/openloading.png new file mode 100644 index 000000000..512333be9 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/mainframe/openloading.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/transparent_background.jpg b/designer-base/src/main/resources/com/fr/design/images/transparent_background.jpg new file mode 100644 index 000000000..b04da96ea Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/transparent_background.jpg differ diff --git a/designer-chart/src/main/java/com/fr/design/chart/gui/ChartWidgetOption.java b/designer-chart/src/main/java/com/fr/design/chart/gui/ChartWidgetOption.java index 42eabf93e..7e64f3d20 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/gui/ChartWidgetOption.java +++ b/designer-chart/src/main/java/com/fr/design/chart/gui/ChartWidgetOption.java @@ -1,10 +1,12 @@ package com.fr.design.chart.gui; import com.fr.base.chart.BaseChartGetter; +import com.fr.chart.chartattr.ChartCollection; import com.fr.design.gui.core.WidgetOption; import com.fr.form.ui.ChartEditor; import com.fr.form.ui.Widget; import com.fr.log.FineLoggerFactory; +import com.fr.plugin.chart.vanchart.VanChart; import javax.swing.Icon; @@ -37,7 +39,12 @@ public class ChartWidgetOption extends WidgetOption { Class clz = widgetClass(); try { ChartEditor widget = clz.newInstance(); - widget.resetChangeChartCollection(BaseChartGetter.createChartCollection(this.chartID)); + ChartCollection chartCollection = (ChartCollection) BaseChartGetter.createChartCollection(this.chartID); + VanChart vanChart = chartCollection.getSelectedChartProvider(VanChart.class); + if (vanChart !=null) { + vanChart.resetAttrInForm(); + } + widget.resetChangeChartCollection(chartCollection); return widget; } catch (InstantiationException e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java index f51755f87..d6acb929a 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java @@ -22,6 +22,7 @@ import com.fr.design.mainframe.chart.gui.ChartStylePane; import com.fr.design.mainframe.chart.gui.ChartTypePane; import com.fr.design.mainframe.chart.gui.type.AbstractChartTypePane; import com.fr.design.mainframe.chart.info.ChartInfoCollector; +import com.fr.form.main.Form; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.plugin.chart.vanchart.VanChart; @@ -198,6 +199,7 @@ public class ChartEditPane extends BasicPane implements AttributeChange, Prepare AbstractChartAttrPane[] otherPaneList = ChartTypeInterfaceManager.getInstance().getAttrPaneArray(chartID, listener); for (int i = 0; i < otherPaneList.length; i++) { otherPaneList[i].addAttributeChangeListener(listener); + otherPaneList[i].registerChartEditPane(this); paneList.add(otherPaneList[i]); } this.isDefaultPane = false; @@ -405,4 +407,14 @@ public class ChartEditPane extends BasicPane implements AttributeChange, Prepare } }); } + + public boolean isInForm() { + if (container != null && container.getEPane() != null) { + Object target = container.getEPane().getTarget(); + if (target instanceof Form) { + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypeButtonPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypeButtonPane.java index e63287246..1fdd6e9fd 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypeButtonPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypeButtonPane.java @@ -67,6 +67,8 @@ public class ChartTypeButtonPane extends BasicBeanPane implemen registerSupportChangeConfigChartClass(VanChart.class); } + private boolean inForm; + private UIButton addButton; private UIButton configButton; private UIButton copyButton; @@ -109,15 +111,10 @@ public class ChartTypeButtonPane extends BasicBeanPane implemen northPane.setLayout(new BorderLayout()); northPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); - JPanel addPanel = new JPanel(); - addPanel.setLayout(new BorderLayout()); - addPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 3)); - addPanel.add(addButton, BorderLayout.CENTER); - JPanel button = new JPanel(); - button.setPreferredSize(new Dimension(95, 20)); - button.setLayout(new GridLayout(1, 4, 0, 0)); - button.add(addPanel); + button.setPreferredSize(new Dimension(89, 20)); + button.setLayout(new GridLayout(1, 4, 3, 0)); + button.add(addButton); button.add(copyButton); button.add(moveForwardButton); button.add(moveBackButton); @@ -133,14 +130,11 @@ public class ChartTypeButtonPane extends BasicBeanPane implemen addButton = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/add.png")); configButton = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/config.png")); copyButton = new UIButton(BaseUtils.readIcon("/com/fr/design/images/m_edit/copy.png")); - copyButton.setBorderPainted(false); copyButton.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_Action_Copy")); moveForwardButton = new UIButton(BaseUtils.readIcon("/com/fr/design/images/control/left.png")); moveForwardButton.setToolTipText(Toolkit.i18nText("Fine-Design_Report_HF_Move_Left")); - moveForwardButton.setBorderPainted(false); moveBackButton = new UIButton(BaseUtils.readIcon("/com/fr/design/images/control/right.png")); moveBackButton.setToolTipText(Toolkit.i18nText("Fine-Design_Report_HF_Move_Right")); - moveBackButton.setBorderPainted(false); initAddButton(); initConfigButton(); initMoveButton(); @@ -160,10 +154,17 @@ public class ChartTypeButtonPane extends BasicBeanPane implemen addButton.addActionListener((e) -> { String name = getNewChartName(); ChartProvider chart = getChangeStateNewChart(); + checkInForm(chart); addNewChart(chart, name, editingCollection.getChartCount()); }); } + private void checkInForm(ChartProvider chart) { + if (inForm) { + chart.resetAttrInForm(); + } + } + private void initConfigButton() { configButton.setPreferredSize(new Dimension(20, 20)); configButton.addActionListener((e) -> showConfigDialog()); @@ -303,7 +304,7 @@ public class ChartTypeButtonPane extends BasicBeanPane implemen } private String getCopyChartName() { - String chartName = "CopyOf" + editingCollection.getChartName(editingCollection.getSelectedIndex()); + String chartName = editingCollection.getChartName(editingCollection.getSelectedIndex()) + "_Copy"; if (!nameRepeated(chartName)) { return chartName; } @@ -680,4 +681,8 @@ public class ChartTypeButtonPane extends BasicBeanPane implemen currentEditingEditor.requestFocus(); } } + + public void refreshChartInForm(boolean inForm) { + this.inForm = inForm; + } } \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypePane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypePane.java index cbbae3022..ac0bfcb57 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypePane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypePane.java @@ -49,6 +49,7 @@ public class ChartTypePane extends AbstractChartAttrPane { private ChartEditPane editPane; private ChartCollection editingCollection; private ActionListener autoButtonListener; + private boolean inForm; @Override protected JPanel createContentPane() { @@ -56,6 +57,7 @@ public class ChartTypePane extends AbstractChartAttrPane { JPanel content = new JPanel(new BorderLayout()); buttonPane = new ChartTypeButtonPane(this); + buttonPane.refreshChartInForm(inForm); content.add(buttonPane, BorderLayout.NORTH); if (editingCollection != null) { @@ -220,8 +222,10 @@ public class ChartTypePane extends AbstractChartAttrPane { } //这一步会替换plot ((AbstractChartTypePane) getSelectedPane()).updateBean(chart); - - reLayoutEditPane(chart,lastPlotID); + if (inForm) { + chart.resetAttrInForm(); + } + reLayoutEditPane(chart, lastPlotID); } protected UIComboBox createComboBox() { @@ -445,5 +449,6 @@ public class ChartTypePane extends AbstractChartAttrPane { */ public void registerChartEditPane(ChartEditPane currentEditPane) { this.editPane = currentEditPane; + this.inForm = editPane.isInForm(); } } \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/van/chart/bubble/VanChartBubbleStylePane.java b/designer-chart/src/main/java/com/fr/van/chart/bubble/VanChartBubbleStylePane.java index de4e88070..cd62fff56 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/bubble/VanChartBubbleStylePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/bubble/VanChartBubbleStylePane.java @@ -21,9 +21,9 @@ public class VanChartBubbleStylePane extends VanChartScatterStylePane { super(listener); } - protected void addVanChartTooltipPane(List paneList){ + protected void addVanChartTooltipPane(List paneList) { Plot plot = getChart().getPlot(); - if(((VanChartBubblePlot) plot).isForceBubble()){ + if (((VanChartBubblePlot) plot).isForceBubble()) { paneList.add(new VanChartForceBubbleTooltipPane(VanChartBubbleStylePane.this)); } else { super.addVanChartTooltipPane(paneList); @@ -31,11 +31,11 @@ public class VanChartBubbleStylePane extends VanChartScatterStylePane { } @Override - protected void addVanChartAreaPane(List paneList) { - if (((VanChartBubblePlot)getChart().getPlot()).isForceBubble()){ - paneList.add(new VanChartForceBubbleAreaPane(getChart().getPlot(), VanChartBubbleStylePane.this)); - }else { - paneList.add(new VanChartAreaPane(getChart().getPlot(), VanChartBubbleStylePane.this)); + protected VanChartAreaPane createVanChartAreaPane() { + if (((VanChartBubblePlot) getChart().getPlot()).isForceBubble()) { + return new VanChartForceBubbleAreaPane(getChart().getPlot(), VanChartBubbleStylePane.this); + } else { + return new VanChartAreaPane(getChart().getPlot(), VanChartBubbleStylePane.this); } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/custom/style/VanChartCustomStylePane.java b/designer-chart/src/main/java/com/fr/van/chart/custom/style/VanChartCustomStylePane.java index a01cbf1cb..da4fa2534 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/custom/style/VanChartCustomStylePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/custom/style/VanChartCustomStylePane.java @@ -11,6 +11,7 @@ import com.fr.plugin.chart.custom.VanChartCustomPlot; import com.fr.plugin.chart.custom.type.CustomPlotType; import com.fr.van.chart.designer.component.richText.VanChartRichEditorPane; import com.fr.van.chart.designer.style.VanChartStylePane; +import com.fr.van.chart.designer.style.background.VanChartAreaPane; import java.util.List; @@ -61,8 +62,8 @@ public class VanChartCustomStylePane extends VanChartStylePane { @Override - protected void addVanChartAreaPane(List paneList) { - paneList.add(new VanChartCustomAreaPane(getChart().getPlot(), VanChartCustomStylePane.this)); + protected VanChartAreaPane createVanChartAreaPane() { + return new VanChartCustomAreaPane(getChart().getPlot(), VanChartCustomStylePane.this); } @Override diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/PlotFactory.java b/designer-chart/src/main/java/com/fr/van/chart/designer/PlotFactory.java index 3167b5f59..4ceeab548 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/PlotFactory.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/PlotFactory.java @@ -34,7 +34,7 @@ import com.fr.van.chart.designer.style.MapRangeLegendPane; import com.fr.van.chart.designer.style.VanChartPlotLegendPane; import com.fr.van.chart.designer.style.VanChartRangeLegendPane; import com.fr.van.chart.designer.style.VanChartStylePane; -import com.fr.van.chart.designer.style.VanLegendPaneWidthOutHighlight; +import com.fr.van.chart.designer.style.VanLegendPaneWidthOutFixedCheck; import com.fr.van.chart.designer.style.label.VanChartGaugePlotLabelPane; import com.fr.van.chart.designer.style.label.VanChartPiePlotLabelPane; import com.fr.van.chart.designer.style.label.VanChartPlotLabelDetailPane; @@ -128,8 +128,8 @@ public class PlotFactory { private static Map, Class> legendMap = new HashMap, Class>(); static { - legendMap.put(VanChartGaugePlot.class, VanLegendPaneWidthOutHighlight.class); - legendMap.put(VanChartMultiPiePlot.class, VanLegendPaneWidthOutHighlight.class); + legendMap.put(VanChartGaugePlot.class, VanLegendPaneWidthOutFixedCheck.class); + legendMap.put(VanChartMultiPiePlot.class, VanLegendPaneWidthOutFixedCheck.class); legendMap.put(VanChartScatterPlot.class, VanChartRangeLegendPane.class); legendMap.put(VanChartBubblePlot.class, VanChartRangeLegendPane.class); legendMap.put(VanChartMapPlot.class, MapRangeLegendPane.class); diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/TableLayout4VanChartHelper.java b/designer-chart/src/main/java/com/fr/van/chart/designer/TableLayout4VanChartHelper.java index f377cee91..030581768 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/TableLayout4VanChartHelper.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/TableLayout4VanChartHelper.java @@ -12,8 +12,8 @@ import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.SwingConstants; import javax.swing.border.Border; -import java.awt.Component; import java.util.Arrays; +import java.awt.Component; /** * 布局 标题+组件 @@ -21,13 +21,13 @@ import java.util.Arrays; public class TableLayout4VanChartHelper { private static final int SMALL_GAP = 20; - public static final int EXPANDABLE_PANE_WIDTH =290; - public static final int EXPANDABLE_PANE_HIGHT =24; + public static final int EXPANDABLE_PANE_WIDTH = 290; + public static final int EXPANDABLE_PANE_HIGHT = 24; public static final int DESCRIPTION_AREA_WIDTH = 60; - public static final int EDIT_AREA_WIDTH =155; + public static final int EDIT_AREA_WIDTH = 155; public static final int SECOND_EDIT_AREA_WIDTH = 143; - public static final int COMPONENT_INTERVAL =12; - public static final Border SECOND_EDIT_AREA_BORDER = BorderFactory.createEmptyBorder(0,12,0,0); + public static final int COMPONENT_INTERVAL = 12; + public static final Border SECOND_EDIT_AREA_BORDER = BorderFactory.createEmptyBorder(0, 12, 0, 0); public static JPanel createExpandablePaneWithTitleTopGap(String title, JPanel panel) { return new UIExpandablePane(title, EXPANDABLE_PANE_WIDTH, EXPANDABLE_PANE_HIGHT, panel) { @@ -43,9 +43,9 @@ public class TableLayout4VanChartHelper { } public static JPanel createExpandablePaneWithTitle(String title, JPanel panel) { - return new UIExpandablePane(title, EXPANDABLE_PANE_WIDTH, EXPANDABLE_PANE_HIGHT, panel){ - protected void setcontentPanelontentPanelBorder (){ - getContentPanel().setBorder(BorderFactory.createEmptyBorder(0 ,5, 0, 0)); + return new UIExpandablePane(title, EXPANDABLE_PANE_WIDTH, EXPANDABLE_PANE_HIGHT, panel) { + protected void setcontentPanelontentPanelBorder() { + getContentPanel().setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); } }; } @@ -54,13 +54,23 @@ public class TableLayout4VanChartHelper { return createGapTableLayoutPane(title, component, EDIT_AREA_WIDTH); } + public static JPanel createGapTableLayoutPaneWithoutTop(String title, Component component) { + return createGapTableLayoutPane(title, component, EDIT_AREA_WIDTH, false); + } + public static JPanel createGapTableLayoutPane(String title, Component component, double componentWidth) { + return createGapTableLayoutPane(title, component, componentWidth, true); + } + + public static JPanel createGapTableLayoutPane(String title, Component component, double componentWidth, boolean topLabel) { double p = TableLayout.PREFERRED; double f = TableLayout.FILL; double[] columnSize = {f, componentWidth}; double[] rowSize = {p, p}; UILabel label = FRWidgetFactory.createLineWrapLabel(title); - label.setVerticalAlignment(SwingConstants.TOP); + if (topLabel) { + label.setVerticalAlignment(SwingConstants.TOP); + } Component[][] components = new Component[][]{ new Component[]{null, null}, new Component[]{label, UIComponentUtils.wrapWithBorderLayoutPane(component)}, @@ -93,60 +103,65 @@ public class TableLayout4VanChartHelper { /** * 标题布局(二级菜单距左边框46) - * @param title 标题 + * + * @param title 标题 * @param component 组件 * @return 布局好的组件 */ - public static JPanel createTableLayoutPaneWithTitle(String title, Component component){ + public static JPanel createTableLayoutPaneWithTitle(String title, Component component) { return TableLayout4VanChartHelper.createTitlePane(title, component, LayoutConstants.CHART_ATTR_TOMARGIN); } /** * 标题布局(二级菜单距左边框46) - * @param label 标题label + * + * @param label 标题label * @param component 组件 * @return 布局好的组件 */ - public static JPanel createTableLayoutPaneWithUILabel(UILabel label, Component component){ + public static JPanel createTableLayoutPaneWithUILabel(UILabel label, Component component) { return TableLayout4VanChartHelper.createTitlePaneWithUILabel(label, component, LayoutConstants.CHART_ATTR_TOMARGIN); } /** * 标题布局(三级菜单距二级左侧20) - * @param title 标题 + * + * @param title 标题 * @param component 组件 * @return 布局好的组件 */ - public static JPanel createTableLayoutPaneWithSmallTitle(String title, Component component){ + public static JPanel createTableLayoutPaneWithSmallTitle(String title, Component component) { return TableLayout4VanChartHelper.createTitlePane(title, component, TableLayout4VanChartHelper.SMALL_GAP); } /** * 标题布局(指定gap) - * @param title 标题 + * + * @param title 标题 * @param component 组件 - * @param gap 距左侧距离 + * @param gap 距左侧距离 * @return 布局好的组件 */ - public static JPanel createTitlePane(String title, Component component, int gap){ + public static JPanel createTitlePane(String title, Component component, int gap) { return createTitlePaneWithUILabel(new UILabel(title), component, gap); } /** * 标题布局(指定gap) - * @param label 标题label + * + * @param label 标题label * @param component 组件 - * @param gap 距左侧距离 + * @param gap 距左侧距离 * @return 布局好的组件 */ - public static JPanel createTitlePaneWithUILabel(UILabel label, Component component, int gap){ + public static JPanel createTitlePaneWithUILabel(UILabel label, Component component, int gap) { double p = TableLayout.PREFERRED; double f = TableLayout.FILL; double[] columnSize = {gap, f}; double[] rowSize = {p, p}; Component[][] components = new Component[][]{ - new Component[]{label,null}, - new Component[]{null,component}, + new Component[]{label, null}, + new Component[]{null, component}, }; return TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize); } diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/component/richText/VanChartRichEditorPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/component/richText/VanChartRichEditorPane.java index 80d49abe3..d36ef487c 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/component/richText/VanChartRichEditorPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/component/richText/VanChartRichEditorPane.java @@ -7,14 +7,13 @@ import com.fr.chart.chartattr.Plot; import com.fr.chart.chartdata.MoreNameCDDefinition; import com.fr.chart.chartdata.OneValueCDDefinition; import com.fr.data.TableDataSource; -import com.fr.data.impl.EmbeddedTableData; +import com.fr.data.impl.NameTableData; import com.fr.design.DesignModelAdapter; import com.fr.design.DesignerEnvManager; import com.fr.design.data.DesignTableDataManager; import com.fr.design.ui.ModernUIPane; import com.fr.general.ComparatorUtils; import com.fr.general.IOUtils; -import com.fr.log.FineLoggerFactory; import com.fr.plugin.chart.base.AttrTooltipRichText; import com.fr.plugin.chart.custom.CustomDefinition; import com.fr.plugin.chart.custom.type.CustomPlotType; @@ -28,6 +27,8 @@ import com.teamdev.jxbrowser.chromium.JSValue; import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.Map; @@ -117,15 +118,9 @@ public class VanChartRichEditorPane { return; } - try { - EmbeddedTableData embeddedTableData = DesignTableDataManager.previewTableDataNotNeedInputParameters(tableDataSource, - tableData, TableData.RESULT_NOT_NEED, false); - - List fieldNames = DesignTableDataManager.getColumnNamesByTableData(embeddedTableData); - VanChartRichEditorPane.fieldNames = fieldNames; - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } + String[] columnNames = DesignTableDataManager.getSelectedColumnNames(tableDataSource, ((NameTableData) tableData).getName()); + VanChartRichEditorPane.fieldNames = new ArrayList<>(); + fieldNames.addAll(Arrays.asList(columnNames)); } public static ModernUIPane createRichEditorPane(AttrTooltipRichText richEditor) { diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java index 8e487a690..c97f3a8ec 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java @@ -8,16 +8,20 @@ import com.fr.chart.chartglyph.ConditionAttr; import com.fr.chart.chartglyph.ConditionCollection; import com.fr.chartx.attr.LargeDataModeType; import com.fr.design.formula.TinyFormulaPane; +import com.fr.design.gui.frpane.UINumberDragPane; +import com.fr.design.gui.frpane.UINumberDragPaneWithPercent; import com.fr.design.gui.ibutton.UIButtonGroup; import com.fr.design.gui.ibutton.UIToggleButton; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ispinner.UISpinner; +import com.fr.design.gui.ispinner.UnsignedIntUISpinner; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.chart.mode.ChartEditContext; +import com.fr.design.widget.FRWidgetFactory; import com.fr.plugin.chart.attr.axis.VanChartAxis; import com.fr.plugin.chart.attr.plot.VanChartPlot; import com.fr.plugin.chart.attr.plot.VanChartRectanglePlot; @@ -33,6 +37,8 @@ import com.fr.plugin.chart.base.VanChartZoom; import com.fr.plugin.chart.gantt.attr.AttrGanttLabel; import com.fr.plugin.chart.map.line.condition.AttrLineEffect; import com.fr.plugin.chart.scatter.attr.ScatterAttrLabel; +import com.fr.plugin.chart.type.AxisType; +import com.fr.plugin.chart.type.ControlType; import com.fr.plugin.chart.vanchart.VanChart; import com.fr.stable.StableUtils; import com.fr.van.chart.custom.component.VanChartHyperLinkPane; @@ -46,14 +52,15 @@ import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.BorderLayout; +import java.awt.CardLayout; import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; +import java.awt.Dimension; public class VanChartInteractivePane extends AbstractVanChartScrollPane { private static final long serialVersionUID = 8135452818502145597L; private static final int AUTO_REFRESH_LEFT_GAP = 18; + private static final double PERCENT = 100.0; protected UICheckBox isSort; protected UICheckBox exportImages; @@ -73,15 +80,20 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { private AutoRefreshPane autoRefreshPane; //图表缩放新设计 恢复用注释。删除下面八行代码。 - private UIButtonGroup zoomWidget; + private UICheckBox zoomWidget; protected UIButtonGroup zoomGesture;//地图手势缩放 - private UIButtonGroup zoomResize; - private TinyFormulaPane from; - private TinyFormulaPane to; private UIButtonGroup zoomType; private JPanel changeEnablePane; private JPanel zoomTypePane; + private UIButtonGroup controlType; + protected JPanel centerPane; + private UISpinner categoryNum; + private UINumberDragPane scaling; + private UIButtonGroup zoomResize; + private TinyFormulaPane from; + private TinyFormulaPane to; + //图表缩放新设计 恢复用注释。取消注释。 //private ZoomPane zoomPane; @@ -127,14 +139,14 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { //new Component[]{createLargeDataModePane(), null}, new Component[]{createAnimationPane(), null}, new Component[]{createAxisRotationPane(new double[]{p, p}, columnSize, plot), null}, - new Component[]{createZoomPane(new double[]{p, p, p}, columnSize, plot), null}, + new Component[]{createZoomPane(plot), null}, new Component[]{createAutoRefreshPane(plot), null}, new Component[]{createHyperlinkPane(), null} } : new Component[][]{ new Component[]{createToolBarPane(getToolBarRowSize(), columnSize), null}, new Component[]{createAnimationPane(), null}, new Component[]{createAxisRotationPane(new double[]{p, p}, columnSize, plot), null}, - new Component[]{createZoomPane(new double[]{p, p, p}, columnSize, plot), null} + new Component[]{createZoomPane(plot), null} }; return TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize); @@ -178,7 +190,7 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { return false; } - protected JPanel createZoomPane(double[] row, double[] col, VanChartPlot plot) { + protected JPanel createZoomPane(VanChartPlot plot) { //图表缩放新设计 恢复用注释。取消注释。 // zoomPane = createZoomPane(); // if (zoomPane == null) { @@ -190,47 +202,118 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { if (!plot.isSupportZoomDirection()) { return null; } - zoomWidget = new UIButtonGroup(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Open"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Close")}); - zoomResize = new UIButtonGroup(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Change"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Non_Adjustment")}); - from = new TinyFormulaPane(); - to = new TinyFormulaPane(); + zoomWidget = new UICheckBox(Toolkit.i18nText("Fine-Design_Chart_Open_Zoom_Control")); + zoomGesture = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Chart_Open"), Toolkit.i18nText("Fine-Design_Chart_Close")}); + JPanel zoomWidgetPane = TableLayout4VanChartHelper.createGapTableLayoutPaneWithoutTop(Toolkit.i18nText("Fine-Design_Chart_Zoom_Widget"), zoomWidget); + JPanel zoomGesturePane = TableLayout4VanChartHelper.createGapTableLayoutPaneWithoutTop(Toolkit.i18nText("Fine-Design_Chart_ZoomGesture"), zoomGesture); zoomType = new UIButtonGroup(getNameArray(), getValueArray()); - zoomGesture = new UIButtonGroup(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Open"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Close")}); + zoomTypePane = getZoomTypePane(zoomType); + + JPanel panel = createZoomPaneContent(zoomWidgetPane, zoomGesturePane, plot); + zoomWidget.addActionListener((event) -> checkZoomPane()); + return TableLayout4VanChartHelper.createExpandablePaneWithTitle(Toolkit.i18nText("Fine-Design_Chart_Use_Zoom"), panel); + } - JPanel zoomWidgetPane = TableLayout4VanChartHelper.createGapTableLayoutPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Zoom_Widget"), zoomWidget); - JPanel zoomGesturePane = TableLayout4VanChartHelper.createGapTableLayoutPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_ZoomGesture"), zoomGesture); + private void createChangeEnablePane(VanChartRectanglePlot plot) { + String scaleAxis = Toolkit.i18nText("Fine-Design_Chart_Scale_Axis"); + String scroll = Toolkit.i18nText("Fine-Design_Chart_Scroll"); + controlType = new UIButtonGroup<>(new String[]{scaleAxis, scroll}, ControlType.values()); + JPanel scaleAxisPane = createScaleAxisPane(); + JPanel scrollPane = createScrollPane(plot); - Component[][] components = new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Widget_Boundary")), zoomResize}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_From")), from}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_To")), to}, + centerPane = new JPanel(new CardLayout()) { + @Override + public Dimension getPreferredSize() { + if (controlType.getSelectedItem() == ControlType.ZOOM) { + return scaleAxisPane.getPreferredSize(); + } else { + return scrollPane.getPreferredSize(); + } + } }; + centerPane.add(scaleAxisPane, scaleAxis); + centerPane.add(scrollPane, scroll); + double p = TableLayout.PREFERRED; double f = TableLayout.FILL; double e = TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH; double[] columnSize = {f, e}; + double[] row = {p, p}; + Component[][] components = new Component[][]{ + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Control_Type")), controlType}, + new Component[]{centerPane, null} + }; changeEnablePane = TableLayout4VanChartHelper.createGapTableLayoutPane(components, row, columnSize); - changeEnablePane.setBorder(BorderFactory.createEmptyBorder(10, 12, 0, 0)); - zoomTypePane = getzoomTypePane(zoomType); - JPanel panel = createZoomPaneContent(zoomWidgetPane, zoomGesturePane, changeEnablePane, zoomTypePane, plot); - zoomWidget.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - checkZoomPane(); + changeEnablePane.setBorder(BorderFactory.createEmptyBorder(5, 12, 0, 0)); + + controlType.addActionListener((event) -> checkCardPane()); + } + + private JPanel createScaleAxisPane() { + zoomResize = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Chart_Change"), Toolkit.i18nText("Fine-Design_Chart_Non_Adjustment")}); + from = new TinyFormulaPane(); + to = new TinyFormulaPane(); + Component[][] components = new Component[][]{ + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Widget_Boundary")), zoomResize}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_From")), from}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_To")), to}, + }; + + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double e = TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH; + double[] columnSize = {f, e}; + double[] row = {p, p, p}; + JPanel resizePane = TableLayout4VanChartHelper.createGapTableLayoutPane(components, row, columnSize); + return resizePane; + } + + + private JPanel createScrollPane(VanChartRectanglePlot plot) { + VanChartAxis vanChartAxis = plot.getCategoryAxisList().get(0); + AxisType axisType = vanChartAxis.getAxisType(); + + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double e = TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH; + double[] columnSize = {f, e}; + double[] row = {p}; + Component[][] components; + if (axisType == AxisType.AXIS_CATEGORY) { + categoryNum = new UnsignedIntUISpinner(1, Double.MAX_VALUE, 1); + components = new Component[][]{ + new Component[]{FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Chart_Initial_Cate_Num")), categoryNum}, + }; + } else { + scaling = new UINumberDragPaneWithPercent(1, 100, 1); + components = new Component[][]{ + new Component[]{FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Chart_Scaling")), scaling}, + }; + } + return TableLayout4VanChartHelper.createGapTableLayoutPane(components, row, columnSize); + } + + protected void checkCardPane() { + if (centerPane != null && controlType != null) { + CardLayout cardLayout = (CardLayout) centerPane.getLayout(); + if (controlType.getSelectedItem() == ControlType.ZOOM) { + cardLayout.show(centerPane, Toolkit.i18nText("Fine-Design_Chart_Scale_Axis")); + } else { + cardLayout.show(centerPane, Toolkit.i18nText("Fine-Design_Chart_Scroll")); } - }); - return TableLayout4VanChartHelper.createExpandablePaneWithTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Use_Zoom"), panel); + } } //图表缩放新设计 恢复用注释。删除下面八个方法getzoomTypePane createZoomPaneContent // checkZoomEnabled getNameArray getValueArray checkZoomPane populateChartZoom updateChartZoom。 - protected JPanel getzoomTypePane(UIButtonGroup zoomType) { - return TableLayout4VanChartHelper.createGapTableLayoutPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Zoom_Direction"), zoomType); + protected JPanel getZoomTypePane(UIButtonGroup zoomType) { + return TableLayout4VanChartHelper.createGapTableLayoutPaneWithoutTop(Toolkit.i18nText("Fine-Design_Chart_Zoom_Direction"), zoomType); } - protected JPanel createZoomPaneContent(JPanel zoomWidgetPane, JPanel zoomGesturePane, JPanel changeEnablePane, JPanel zoomTypePane, VanChartPlot plot) { + protected JPanel createZoomPaneContent(JPanel zoomWidgetPane, JPanel zoomGesturePane, VanChartPlot plot) { JPanel panel = new JPanel(new BorderLayout(0, 4)); if (plot.isSupportZoomCategoryAxis()) {//支持缩放控件 + createChangeEnablePane((VanChartRectanglePlot) plot); panel.add(zoomWidgetPane, BorderLayout.NORTH); panel.add(changeEnablePane, BorderLayout.CENTER); } @@ -242,17 +325,18 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { if (zoomWidget != null && axisRotation != null) { if (axisRotation.getSelectedIndex() == 0) { //只有开启坐标轴翻转,才需要将缩放控件强制关闭。 - zoomWidget.setSelectedIndex(1); + zoomWidget.setSelected(false); } checkZoomPane(); zoomWidget.setEnabled(axisRotation.getSelectedIndex() == 1); } + checkCardPane(); } protected String[] getNameArray() { - return new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_X_Axis"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Y_Axis") - , com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_XY_Axis"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Use_None")}; + return new String[]{Toolkit.i18nText("Fine-Design_Chart_X_Axis"), Toolkit.i18nText("Fine-Design_Chart_Y_Axis") + , Toolkit.i18nText("Fine-Design_Chart_XY_Axis"), Toolkit.i18nText("Fine-Design_Chart_Use_None")}; } protected String[] getValueArray() { @@ -262,9 +346,11 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { } private void checkZoomPane() { - boolean zoomWidgetEnabled = zoomWidget.getSelectedIndex() == 0; - changeEnablePane.setVisible(zoomWidgetEnabled); - zoomType.setEnabled(!zoomWidgetEnabled); + boolean zoomWidgetEnabled = zoomWidget.isSelected(); + if (changeEnablePane != null) { + changeEnablePane.setVisible(zoomWidgetEnabled); + } + zoomTypePane.setVisible(!zoomWidgetEnabled); } private void populateChartZoom(VanChart chart) { @@ -272,20 +358,31 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { if (zoom == null) { zoom = new VanChartZoom(); } - zoomWidget.setSelectedIndex(zoom.isZoomVisible() ? 0 : 1); + zoomWidget.setSelected(zoom.isZoomVisible()); zoomGesture.setSelectedIndex(zoom.isZoomGesture() ? 0 : 1); - zoomResize.setSelectedIndex(zoom.isZoomResize() ? 0 : 1); - if (zoom.getFrom() instanceof BaseFormula) { - from.populateBean(((BaseFormula) zoom.getFrom()).getContent()); - } else { - from.populateBean(Utils.objectToString(zoom.getFrom())); - } - if (zoom.getTo() instanceof BaseFormula) { - to.populateBean(((BaseFormula) zoom.getTo()).getContent()); - } else { - to.populateBean(Utils.objectToString(zoom.getTo())); - } zoomType.setSelectedItem(zoom.getZoomType()); + + if (changeEnablePane != null) { + controlType.setSelectedItem(zoom.getControlType()); + + zoomResize.setSelectedIndex(zoom.isZoomResize() ? 0 : 1); + if (zoom.getFrom() instanceof BaseFormula) { + from.populateBean(((BaseFormula) zoom.getFrom()).getContent()); + } else { + from.populateBean(Utils.objectToString(zoom.getFrom())); + } + if (zoom.getTo() instanceof BaseFormula) { + to.populateBean(((BaseFormula) zoom.getTo()).getContent()); + } else { + to.populateBean(Utils.objectToString(zoom.getTo())); + } + if (categoryNum != null) { + categoryNum.setValue(zoom.getCategoryNum()); + } + if (scaling != null) { + scaling.populateBean(zoom.getScaling() * PERCENT); + } + } } private void updateChartZoom(VanChart chart) { @@ -294,26 +391,38 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { zoom = new VanChartZoom(); chart.setVanChartZoom(zoom); } - zoom.setZoomVisible(zoomWidget.getSelectedIndex() == 0); + zoom.setZoomVisible(zoomWidget.isSelected()); zoom.setZoomGesture(zoomGesture.getSelectedIndex() == 0); - zoom.setZoomResize(zoomResize.getSelectedIndex() == 0); - String fromString = from.updateBean(); - Object fromObject; - if (StableUtils.maybeFormula(fromString)) { - fromObject = BaseFormula.createFormulaBuilder().build(fromString); - } else { - fromObject = fromString; - } - zoom.setFrom(fromObject); - String toString = to.updateBean(); - Object toObject; - if (StableUtils.maybeFormula(toString)) { - toObject = BaseFormula.createFormulaBuilder().build(toString); - } else { - toObject = toString; - } - zoom.setTo(toObject); zoom.setZoomType(zoomType.getSelectedItem()); + if (changeEnablePane != null) { + zoom.setControlType(controlType.getSelectedItem()); + if (zoom.getControlType() == ControlType.ZOOM) { + zoom.setZoomResize(zoomResize.getSelectedIndex() == 0); + String fromString = from.updateBean(); + Object fromObject; + if (StableUtils.maybeFormula(fromString)) { + fromObject = BaseFormula.createFormulaBuilder().build(fromString); + } else { + fromObject = fromString; + } + zoom.setFrom(fromObject); + String toString = to.updateBean(); + Object toObject; + if (StableUtils.maybeFormula(toString)) { + toObject = BaseFormula.createFormulaBuilder().build(toString); + } else { + toObject = toString; + } + zoom.setTo(toObject); + } else { + if (categoryNum != null) { + zoom.setCategoryNum((int) categoryNum.getValue()); + } + if (scaling != null) { + zoom.setScaling(scaling.updateBean() / PERCENT); + } + } + } } protected ZoomPane createZoomPane() { @@ -386,12 +495,12 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { double f = TableLayout.FILL; double e = TableLayout4VanChartHelper.EDIT_AREA_WIDTH; double[] columnSize = {f, e}; - double[] rowSize = {p,p}; + double[] rowSize = {p, p}; Component[][] components = new Component[][]{ - new Component[]{null,null}, - new Component[]{chartAnimationLabel,isChartAnimation} + new Component[]{null, null}, + new Component[]{chartAnimationLabel, isChartAnimation} }; - JPanel panel = TableLayout4VanChartHelper.createGapTableLayoutPane(components,rowSize,columnSize); + JPanel panel = TableLayout4VanChartHelper.createGapTableLayoutPane(components, rowSize, columnSize); return TableLayout4VanChartHelper.createExpandablePaneWithTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Animation"), panel); } @@ -473,7 +582,6 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { //图表缩放新设计 恢复用注释。删除下面三行代码。 if (plot.isSupportZoomDirection()) {//支持缩放方向=方向+控件 populateChartZoom((VanChart) chart); - checkZoomPane(); } if (plot.getAxisPlotType() == AxisPlotType.RECTANGLE) { diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePaneWithMapZoom.java b/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePaneWithMapZoom.java index 7de7ca3d5..3ed3251d0 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePaneWithMapZoom.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePaneWithMapZoom.java @@ -12,7 +12,7 @@ public class VanChartInteractivePaneWithMapZoom extends VanChartInteractivePaneW //图表缩放新设计 恢复用注释。删除下面方法 createZoomPaneContent。 @Override - protected JPanel createZoomPaneContent(JPanel zoomWidgetPane, JPanel zoomGesturePane, JPanel changeEnablePane, JPanel zoomTypePane, VanChartPlot plot) { + protected JPanel createZoomPaneContent(JPanel zoomWidgetPane, JPanel zoomGesturePane, VanChartPlot plot) { JPanel panel = new JPanel(new BorderLayout(0, 4)); panel.add(zoomWidgetPane, BorderLayout.NORTH); panel.add(zoomGesturePane, BorderLayout.CENTER); diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/HeatMapRangeLegendPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/HeatMapRangeLegendPane.java index d77a106a2..556f9e0fd 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/HeatMapRangeLegendPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/HeatMapRangeLegendPane.java @@ -17,6 +17,6 @@ public class HeatMapRangeLegendPane extends MapRangeLegendPane { } protected JPanel createCommonLegendPane(){ - return this.createLegendPaneWithoutHighlight(); + return this.createLegendPaneWithoutFixedCheck(); } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartPlotLegendPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartPlotLegendPane.java index 5a16aa4c8..4ba1abb7d 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartPlotLegendPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartPlotLegendPane.java @@ -72,9 +72,9 @@ public class VanChartPlotLegendPane extends BasicPane { //private LimitPane limitPane; //高亮显示的按钮 - private UILabel highlightLabel; - private UIButtonGroup highlightButton; - private JPanel highlightPane; + private UILabel fixedCheckLabel; + private UICheckBox fixedCheck; + private JPanel fixedCheckPane; private VanChartStylePane parent; @@ -91,8 +91,8 @@ public class VanChartPlotLegendPane extends BasicPane { this.plot = plot; } - public JPanel getHighlightPane() { - return highlightPane; + public JPanel getFixedCheckPane() { + return fixedCheckPane; } public VanChartStylePane getLegendPaneParent() { @@ -135,7 +135,7 @@ public class VanChartPlotLegendPane extends BasicPane { }); } - protected JPanel createLegendPaneWithoutHighlight() { + protected JPanel createLegendPaneWithoutFixedCheck() { borderPane = new VanChartBorderWithRadiusPane(); backgroundPane = creatBackgroundPane(); @@ -162,11 +162,11 @@ public class VanChartPlotLegendPane extends BasicPane { protected JPanel createLegendPane() { borderPane = new VanChartBorderWithRadiusPane(); backgroundPane = creatBackgroundPane(); - highlightPane = createHighlightPane(); + fixedCheckPane = createFixedCheckPane(); JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.add(createDisplayStrategy(), BorderLayout.CENTER); - panel.add(highlightPane, BorderLayout.SOUTH); + panel.add(fixedCheckPane, BorderLayout.SOUTH); double p = TableLayout.PREFERRED; double f = TableLayout.FILL; @@ -319,9 +319,9 @@ public class VanChartPlotLegendPane extends BasicPane { // return limitPane; } - private JPanel createHighlightPane() { - highlightButton = new UIButtonGroup<>(new String[]{Toolkit.i18nText("Fine-Design_Chart_On"), Toolkit.i18nText("Fine-Design_Chart_Off")}, new Boolean[]{true, false}); - highlightLabel = new UILabel(Toolkit.i18nText("Fine-Design_Chart_Highlight")); + private JPanel createFixedCheckPane() { + fixedCheck = new UICheckBox(Toolkit.i18nText("Fine-Engine_Chart_Open_Fixed_Display")); + fixedCheckLabel = new UILabel(Toolkit.i18nText("Fine-Engine_Chart_Fixed_Display")); double p = TableLayout.PREFERRED; double f = TableLayout.FILL; double e = TableLayout4VanChartHelper.EDIT_AREA_WIDTH; @@ -329,7 +329,7 @@ public class VanChartPlotLegendPane extends BasicPane { double[] rowSize = {p, p}; Component[][] components = new Component[][]{ new Component[]{null, null}, - new Component[]{highlightLabel, highlightButton} + new Component[]{fixedCheckLabel, fixedCheck} }; return TableLayout4VanChartHelper.createGapTableLayoutPane(components, rowSize, columnSize); } @@ -408,8 +408,8 @@ public class VanChartPlotLegendPane extends BasicPane { //legend.setLimitAttribute(limitPane.updateBean()); legend.setFloatPercentX(customFloatPositionPane.getFloatPosition_x()); legend.setFloatPercentY(customFloatPositionPane.getFloatPosition_y()); - if (highlightButton != null && highlightButton.getSelectedItem() != null) { - legend.setHighlight(highlightButton.getSelectedItem()); + if (fixedCheck != null) { + legend.setHighlight(fixedCheck.isSelected()); } } @@ -431,11 +431,11 @@ public class VanChartPlotLegendPane extends BasicPane { maxProportion.populateBean(legend.getMaxHeight()); //区域显示策略 恢复用注释。取消注释。 //limitPane.populateBean(legend.getLimitAttribute()); - if (highlightButton != null) { - highlightButton.setSelectedItem(legend.isHighlight()); + if (fixedCheck != null) { + fixedCheck.setSelected(legend.isHighlight()); boolean largeDataModel = PlotFactory.largeDataModel(plot); - highlightButton.setEnabled(!largeDataModel); - highlightLabel.setEnabled(!largeDataModel); + fixedCheck.setEnabled(!largeDataModel); + fixedCheckLabel.setEnabled(!largeDataModel); } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartRangeLegendPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartRangeLegendPane.java index 5fa030a28..cae5bd30c 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartRangeLegendPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartRangeLegendPane.java @@ -114,7 +114,7 @@ public class VanChartRangeLegendPane extends VanChartPlotLegendPane { } private void checkHighlightVisible() { - JPanel highlightPane = this.getHighlightPane(); + JPanel highlightPane = this.getFixedCheckPane(); if (highlightPane != null) { highlightPane.setVisible(legendType != LegendType.GRADUAL); diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartStylePane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartStylePane.java index 53619765c..7ca77a9fc 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartStylePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartStylePane.java @@ -3,6 +3,7 @@ package com.fr.van.chart.designer.style; import com.fr.chart.chartattr.Plot; import com.fr.design.dialog.BasicPane; import com.fr.design.gui.frpane.AttributeChangeListener; +import com.fr.design.mainframe.chart.ChartEditPane; import com.fr.design.mainframe.chart.gui.ChartStylePane; import com.fr.plugin.chart.attr.plot.VanChartAxisPlot; import com.fr.van.chart.designer.component.richText.VanChartRichEditorPane; @@ -19,14 +20,20 @@ public class VanChartStylePane extends ChartStylePane { private static final long serialVersionUID = 186776958263021761L; + private ChartEditPane chartEditPane; + public VanChartStylePane(AttributeChangeListener listener) { super(listener); } - protected java.util.List getPaneList() { - java.util.List paneList = new ArrayList(); + protected List getPaneList() { + List paneList = new ArrayList(); Plot plot = getChart().getPlot(); - paneList.add(createVanChartTitlePane()); + + boolean inForm = chartEditPane != null ? chartEditPane.isInForm() : false; + VanChartTitlePane vanChartTitlePane = createVanChartTitlePane(); + vanChartTitlePane.refreshTooltipLabel(inForm); + paneList.add(vanChartTitlePane); if (plot.isSupportLegend()) { paneList.add(new VanChartLegendPane(VanChartStylePane.this)); } @@ -47,7 +54,9 @@ public class VanChartStylePane extends ChartStylePane { } } - addVanChartAreaPane(paneList); + VanChartAreaPane vanChartAreaPane = createVanChartAreaPane(); + vanChartAreaPane.refreshTooltipLabel(inForm); + paneList.add(vanChartAreaPane); addVanChartTooltipPane(paneList); @@ -61,8 +70,8 @@ public class VanChartStylePane extends ChartStylePane { protected void addOtherAxisPane(java.util.List paneList, Plot plot) { } - protected void addVanChartAreaPane(List paneList) { - paneList.add(new VanChartAreaPane(getChart().getPlot(), VanChartStylePane.this)); + protected VanChartAreaPane createVanChartAreaPane() { + return new VanChartAreaPane(getChart().getPlot(), VanChartStylePane.this); } protected void createVanChartAxisPane(List paneList, VanChartAxisPlot plot) { @@ -80,4 +89,9 @@ public class VanChartStylePane extends ChartStylePane { public void refreshTableFieldNames() { VanChartRichEditorPane.refreshCommonChartFieldNames(getChart()); } + + public void registerChartEditPane(ChartEditPane currentEditPane) { + this.chartEditPane = currentEditPane; + } + } \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartTitlePane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartTitlePane.java index 59652a4af..10a313af7 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartTitlePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanChartTitlePane.java @@ -13,6 +13,7 @@ import com.fr.design.gui.ibutton.UIButtonGroup; import com.fr.design.gui.ibutton.UIToggleButton; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.chart.PaneTitleConstants; @@ -36,6 +37,7 @@ import javax.swing.SwingConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; import java.awt.Point; import java.awt.event.ActionEvent; @@ -69,6 +71,7 @@ public class VanChartTitlePane extends AbstractVanChartScrollPane { private JPanel maxProportionPane; //区域显示策略 恢复用注释。取消注释。 //private LimitPane limitPane; + private UILabel tooltipLabel; protected VanChartStylePane parent; @@ -88,21 +91,30 @@ public class VanChartTitlePane extends AbstractVanChartScrollPane { } private void initComponents() { - isTitleVisible = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Title_Visible")); - titlePane = createTitlePane(); + isTitleVisible = new UICheckBox(Toolkit.i18nText("Fine-Design_Chart_Title_Visible")); + tooltipLabel = new UILabel("" + Toolkit.i18nText("Fine-Design_Chart_Title_Tooltip") + ""); + tooltipLabel.setForeground(Color.gray); + tooltipLabel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10)); + tooltipLabel.setVisible(false); + + JPanel panel = new JPanel(); + panel.setLayout(new BorderLayout()); + panel.add(isTitleVisible, BorderLayout.NORTH); + panel.add(tooltipLabel, BorderLayout.CENTER); + titlePane = createTitlePane(); double p = TableLayout.PREFERRED; double f = TableLayout.FILL; double[] columnSize = {f}; double[] rowSize = {p, p, p}; Component[][] components = new Component[][]{ - new Component[]{isTitleVisible}, + new Component[]{panel}, new Component[]{titlePane} }; - JPanel panel = TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize); + JPanel panel1 = TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize); this.setLayout(new BorderLayout()); - this.add(panel, BorderLayout.CENTER); + this.add(panel1, BorderLayout.CENTER); isTitleVisible.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -370,4 +382,7 @@ public class VanChartTitlePane extends AbstractVanChartScrollPane { ChartInfoCollector.getInstance().updateChartConfig(chart, ConfigType.TITLE, chart.getBuryingPointTitleConfig()); } + public void refreshTooltipLabel(boolean inForm) { + tooltipLabel.setVisible(inForm); + } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanLegendPaneWidthOutFixedCheck.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanLegendPaneWidthOutFixedCheck.java new file mode 100644 index 000000000..80dd6d9c2 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanLegendPaneWidthOutFixedCheck.java @@ -0,0 +1,21 @@ +package com.fr.van.chart.designer.style; + +import javax.swing.JPanel; + +/** + * Created by eason on 2016/12/14. + */ +public class VanLegendPaneWidthOutFixedCheck extends VanChartPlotLegendPane{ + + public VanLegendPaneWidthOutFixedCheck(){ + + } + + public VanLegendPaneWidthOutFixedCheck(VanChartStylePane parent){ + super(parent); + } + + protected JPanel createLegendPane(){ + return this.createLegendPaneWithoutFixedCheck(); + } +} diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanLegendPaneWidthOutHighlight.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanLegendPaneWidthOutHighlight.java deleted file mode 100644 index 8387a2053..000000000 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/VanLegendPaneWidthOutHighlight.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.fr.van.chart.designer.style; - -import javax.swing.JPanel; - -/** - * Created by eason on 2016/12/14. - */ -public class VanLegendPaneWidthOutHighlight extends VanChartPlotLegendPane{ - - public VanLegendPaneWidthOutHighlight(){ - - } - - public VanLegendPaneWidthOutHighlight(VanChartStylePane parent){ - super(parent); - } - - protected JPanel createLegendPane(){ - return this.createLegendPaneWithoutHighlight(); - } -} diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartTimeAxisPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartTimeAxisPane.java index f960b4aff..1a0b78982 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartTimeAxisPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartTimeAxisPane.java @@ -293,7 +293,7 @@ public class VanChartTimeAxisPane extends VanChartBaseAxisPane { DateEditor dateEditor = (DateEditor)minValueField.getCurrentEditor(); String dateString = dateEditor.getUIDatePickerFormat().format(datetmp); timeAxis.setCustomMinValue(StringUtils.isNotEmpty(dateString)); - timeAxis.setMinValue(BaseFormula.createFormulaBuilder().build(dateString)); + timeAxis.setMinValue(createDataFormula(dateString)); } } else { timeAxis.setCustomMinValue(false); @@ -308,7 +308,7 @@ public class VanChartTimeAxisPane extends VanChartBaseAxisPane { DateEditor dateEditor = (DateEditor)maxValueField.getCurrentEditor(); String dateString = dateEditor.getUIDatePickerFormat().format(datetmp); timeAxis.setCustomMaxValue(StringUtils.isNotEmpty(dateString)); - timeAxis.setMaxValue(BaseFormula.createFormulaBuilder().build(dateString)); + timeAxis.setMaxValue(createDataFormula(dateString)); } } else { timeAxis.setCustomMaxValue(false); @@ -332,6 +332,11 @@ public class VanChartTimeAxisPane extends VanChartBaseAxisPane { checkBoxUse(); } + private BaseFormula createDataFormula(String dateString) { + String formulaString = "\"" + dateString + "\""; + return BaseFormula.createFormulaBuilder().build(formulaString); + } + public void populate(VanChartTimeAxis timeAxis){ // 最小值 if (timeAxis.isCustomMinValue() && timeAxis.getMinValue() != null) { diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartAreaBackgroundPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartAreaBackgroundPane.java index 6cef622eb..19f5d4051 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartAreaBackgroundPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartAreaBackgroundPane.java @@ -3,6 +3,8 @@ package com.fr.van.chart.designer.style.background; import com.fr.chart.chartattr.Chart; import com.fr.chart.chartattr.Plot; import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.chart.PaneTitleConstants; @@ -12,8 +14,10 @@ import com.fr.van.chart.designer.component.background.VanChartBackgroundPane; import com.fr.van.chart.designer.component.border.VanChartBorderWithRadiusPane; import com.fr.van.chart.designer.style.background.radar.VanChartRadarAxisAreaPane; +import javax.swing.BorderFactory; import javax.swing.JPanel; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; //图表区|绘图区 边框和背景 @@ -25,12 +29,13 @@ public class VanChartAreaBackgroundPane extends AbstractVanChartScrollPane" + Toolkit.i18nText("Fine-Design_Chart_Background_Tooltip") + ""); + tooltipLabel.setForeground(Color.gray); + tooltipLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 5, 10)); + contentPane.add(tooltipLabel, BorderLayout.NORTH); + tooltipLabel.setVisible(false); + } return contentPane; } @@ -68,11 +81,11 @@ public class VanChartAreaBackgroundPane extends AbstractVanChartScrollPane implements AutoSele JPanel pane = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0)); if (nameArray.length > 1) { pane.add(tabPane); - tabPane.setBorder(BorderFactory.createEmptyBorder(0,5,0,0)); + tabPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); this.add(pane, BorderLayout.NORTH); } } - centerPane.setBorder(BorderFactory.createEmptyBorder(10,0,0,0)); + centerPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); this.add(centerPane, BorderLayout.CENTER); } /** * 界面 使用标题 - * @return 标题 + * + * @return 标题 */ public String title4PopupWindow() { return PaneTitleConstants.CHART_STYLE_AREA_TITLE; @@ -66,7 +67,7 @@ public class VanChartAreaPane extends ThirdTabPane implements AutoSele paneList.add(new NamePane(areaPane.title4PopupWindow(), areaPane)); - if(plot.isSupportPlotBackground()) { + if (plot.isSupportPlotBackground()) { paneList.add(new NamePane(plotPane.title4PopupWindow(), plotPane)); } return paneList; @@ -111,4 +112,10 @@ public class VanChartAreaPane extends ThirdTabPane implements AutoSele } } } + + public void refreshTooltipLabel(boolean inForm) { + if (areaPane != null) { + areaPane.refreshTooltipLabel(inForm); + } + } } \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/van/chart/drillmap/designer/other/VanChartDrillMapInteractivePane.java b/designer-chart/src/main/java/com/fr/van/chart/drillmap/designer/other/VanChartDrillMapInteractivePane.java index 0122b529b..c439c4d4d 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/drillmap/designer/other/VanChartDrillMapInteractivePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/drillmap/designer/other/VanChartDrillMapInteractivePane.java @@ -43,14 +43,14 @@ public class VanChartDrillMapInteractivePane extends VanChartInteractivePaneWith Component[][] components = ChartEditContext.normalMode() ? new Component[][]{ new Component[]{createToolBarPane(new double[]{p, p, p}, columnSize), null}, new Component[]{createAnimationPane(), null}, - new Component[]{createZoomPane(new double[]{p, p, p}, columnSize, plot), null}, + new Component[]{createZoomPane(plot), null}, new Component[]{createDrillToolsPane(), null}, new Component[]{createAutoRefreshPane(plot), null}, new Component[]{createHyperlinkPane(), null} } : new Component[][]{ new Component[]{createToolBarPane(new double[]{p, p, p}, columnSize), null}, new Component[]{createAnimationPane(), null}, - new Component[]{createZoomPane(new double[]{p, p, p}, columnSize, plot), null}, + new Component[]{createZoomPane(plot), null}, new Component[]{createDrillToolsPane(), null} }; diff --git a/designer-chart/src/main/java/com/fr/van/chart/map/designer/data/component/SeriesTypeUseComboxPaneWithOutFilter.java b/designer-chart/src/main/java/com/fr/van/chart/map/designer/data/component/SeriesTypeUseComboxPaneWithOutFilter.java index db545b9d4..1b567b474 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/map/designer/data/component/SeriesTypeUseComboxPaneWithOutFilter.java +++ b/designer-chart/src/main/java/com/fr/van/chart/map/designer/data/component/SeriesTypeUseComboxPaneWithOutFilter.java @@ -26,6 +26,7 @@ public class SeriesTypeUseComboxPaneWithOutFilter extends SeriesTypeUseComboxPan protected void initComponents() { super.initComponents(); this.setSelectedIndex(1); + this.checkCardPane(); } @Override diff --git a/designer-chart/src/main/java/com/fr/van/chart/map/designer/style/label/VanChartMapLabelContentPane.java b/designer-chart/src/main/java/com/fr/van/chart/map/designer/style/label/VanChartMapLabelContentPane.java index ce3e34ba7..680a7e4f2 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/map/designer/style/label/VanChartMapLabelContentPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/map/designer/style/label/VanChartMapLabelContentPane.java @@ -1,6 +1,9 @@ package com.fr.van.chart.map.designer.style.label; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; import com.fr.design.ui.ModernUIPane; import com.fr.plugin.chart.base.AttrTooltipContent; import com.fr.plugin.chart.base.format.AttrTooltipAreaNameFormat; @@ -10,6 +13,7 @@ import com.fr.plugin.chart.base.format.AttrTooltipPercentFormat; import com.fr.plugin.chart.base.format.AttrTooltipSeriesFormat; import com.fr.plugin.chart.base.format.AttrTooltipValueFormat; import com.fr.plugin.chart.type.TextAlign; +import com.fr.van.chart.designer.TableLayout4VanChartHelper; import com.fr.van.chart.designer.component.VanChartLabelContentPane; import com.fr.van.chart.designer.component.format.MapAreaNameFormatPaneWithCheckBox; import com.fr.van.chart.designer.component.format.PercentFormatPaneWithCheckBox; @@ -23,12 +27,17 @@ import com.fr.van.chart.designer.style.VanChartStylePane; import com.fr.van.chart.map.designer.style.VanChartMapRichTextFieldListPane; import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Component; /** * Created by Mitisky on 16/5/20. */ public class VanChartMapLabelContentPane extends VanChartLabelContentPane { + private UICheckBox showAllSeries; + private JPanel checkPane; + public VanChartMapLabelContentPane(VanChartStylePane parent, JPanel showOnPane, boolean inCondition) { super(parent, showOnPane, inCondition); } @@ -55,6 +64,31 @@ public class VanChartMapLabelContentPane extends VanChartLabelContentPane { }; } + protected JPanel getLabelContentPane(JPanel contentPane) { + showAllSeries = new UICheckBox(Toolkit.i18nText("Fine-Design_Chart_Show_All_Series")); + + double f = TableLayout.FILL; + double e = TableLayout4VanChartHelper.EDIT_AREA_WIDTH; + double[] columnSize = {f, e}; + double p = TableLayout.PREFERRED; + double[] row = {p, p}; + Component[][] components = { + new Component[]{null, null}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Display_Strategy")), showAllSeries} + }; + checkPane = TableLayout4VanChartHelper.createGapTableLayoutPane(components, row, columnSize); + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(contentPane, BorderLayout.CENTER); + panel.add(checkPane, BorderLayout.SOUTH); + return createTableLayoutPaneWithTitle(Toolkit.i18nText("Fine-Design_Chart_Content"), panel); + } + + protected void checkCardPane() { + super.checkCardPane(); + checkPane.setVisible(getContent().getSelectedIndex() == COMMON_INDEX); + } + protected String[] getRichTextFieldNames() { return new String[]{ Toolkit.i18nText("Fine-Design_Chart_Area_Name"), @@ -82,4 +116,15 @@ public class VanChartMapLabelContentPane extends VanChartLabelContentPane { content.setRichTextValueFormat(new AttrTooltipMapValueFormat()); return content; } + + public AttrTooltipContent updateBean() { + AttrTooltipContent attrTooltipContent = super.updateBean(); + attrTooltipContent.setShowAllSeries(showAllSeries.isSelected()); + return attrTooltipContent; + } + + public void populateBean(AttrTooltipContent attrTooltipContent) { + super.populateBean(attrTooltipContent); + showAllSeries.setSelected(attrTooltipContent.isShowAllSeries()); + } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/pie/RadiusCardLayoutPane.java b/designer-chart/src/main/java/com/fr/van/chart/pie/RadiusCardLayoutPane.java index 7befd40e7..db13b2806 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/pie/RadiusCardLayoutPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/pie/RadiusCardLayoutPane.java @@ -42,7 +42,7 @@ public class RadiusCardLayoutPane extends BasicBeanPane { Map paneList = new HashMap(); radiusType = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Chart_Auto"), Toolkit.i18nText("Fine-Design_Chart_Fixed")}); - radius = new UISpinnerWithPx(100); + radius = new UISpinnerWithPx(1, Double.MAX_VALUE, 1, 100); radiusContent = new JPanel(new BorderLayout()); radiusContent.add(radius, BorderLayout.CENTER); @@ -55,12 +55,12 @@ public class RadiusCardLayoutPane extends BasicBeanPane { radiusType.setSelectedIndex(0); - cardPane = new VanChartCardLayoutPane(paneList, "auto"){ + cardPane = new VanChartCardLayoutPane(paneList, "auto") { @Override public Dimension getPreferredSize() { if (radiusType.getSelectedIndex() == 1) { return radiusContent.getPreferredSize(); - }else { + } else { return new Dimension(0, 0); } } @@ -69,15 +69,15 @@ public class RadiusCardLayoutPane extends BasicBeanPane { double p = TableLayout.PREFERRED; double f = TableLayout.FILL; double[] columnSize = {p, f}; - double[] rowSize = {p,p}; + double[] rowSize = {p, p}; Component[][] components = new Component[][]{ - new Component[]{radiusType,null}, + new Component[]{radiusType, null}, new Component[]{cardPane, null}, }; JPanel panel = TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize); - this.setLayout(new BorderLayout(0,0)); + this.setLayout(new BorderLayout(0, 0)); this.add(panel, BorderLayout.CENTER); @@ -90,7 +90,7 @@ public class RadiusCardLayoutPane extends BasicBeanPane { @Override public void populateBean(Plot plot) { - if (plot instanceof VanChartRadiusPlot){ + if (plot instanceof VanChartRadiusPlot) { VanChartRadiusPlot radiusPlot = (VanChartRadiusPlot) plot; VanChartRadius vanChartRadius = radiusPlot.getRadius(); radiusType.setSelectedIndex(vanChartRadius.getRadiusType() == RadiusType.AUTO ? 0 : 1); @@ -102,7 +102,7 @@ public class RadiusCardLayoutPane extends BasicBeanPane { public void updateBean(Plot plot) { //更新半径 - if (plot instanceof VanChartRadiusPlot){ + if (plot instanceof VanChartRadiusPlot) { VanChartRadiusPlot radiusPlot = (VanChartRadiusPlot) plot; VanChartRadius vanChartRadius = radiusPlot.getRadius(); vanChartRadius.setRadiusType(radiusType.getSelectedIndex() == 0 ? RadiusType.AUTO : RadiusType.FIXED); diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java index 932338a3f..4b3147c0a 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java @@ -72,7 +72,7 @@ public class FRAbsoluteLayoutAdapter extends FRBodyLayoutAdapter { } XLayoutContainer topLayout = XCreatorUtils.getHotspotContainer((XCreator)comp).getTopLayout(); if(topLayout != null){ - if (topLayout.isEditable()){ + if (topLayout.isDragInAble() || topLayout.isEditable()){ return topLayoutAccept(creator, x, y); } //绝对布局嵌套,处于内层,不可编辑,不添加,topLayout只能获取到最外层可编辑的布局 diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java index 22d74d774..c893268ba 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java @@ -19,12 +19,7 @@ import com.fr.design.designer.creator.cardlayout.XWCardTitleLayout; import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; import com.fr.design.designer.properties.FRFitLayoutConstraints; import com.fr.design.designer.properties.FRFitLayoutPropertiesGroupModel; -import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.fun.FormWidgetOptionProvider; -import com.fr.design.mainframe.FormDesigner; -import com.fr.design.mainframe.JForm; -import com.fr.design.mainframe.JTemplate; -import com.fr.design.mainframe.WidgetPropertyPane; import com.fr.design.utils.ComponentUtils; import com.fr.form.ui.LayoutBorderStyle; import com.fr.form.ui.container.WAbsoluteLayout; @@ -169,7 +164,7 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { //布局控件要先判断是不是可编辑 XLayoutContainer topLayout = XCreatorUtils.getHotspotContainer((XCreator) comp).getTopLayout(); - boolean access = topLayout != null && !isMatchEdge && !topLayout.isEditable() && !topLayout.acceptType(XWAbsoluteLayout.class) && !isExtraContainer(comp); + boolean access = topLayout != null && !isMatchEdge && !topLayout.isEditable() && !topLayout.acceptType(XWAbsoluteLayout.class) && !isExtraContainer(comp) && !topLayout.isDragInAble(); if (access) { return false; } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/location/AccessDirection.java b/designer-form/src/main/java/com/fr/design/designer/beans/location/AccessDirection.java index 3538d2fd9..eae04d998 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/location/AccessDirection.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/location/AccessDirection.java @@ -5,13 +5,17 @@ package com.fr.design.designer.beans.location; import com.fr.design.beans.location.Absorptionline; import com.fr.design.beans.location.MoveUtils; -import com.fr.design.designer.creator.*; +import com.fr.design.designer.creator.XCreatorUtils; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XWAbsoluteLayout; +import com.fr.design.designer.creator.XWBorderLayout; +import com.fr.design.designer.creator.XWParameterLayout; import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.FormSelection; import com.fr.design.utils.ComponentUtils; +import com.fr.env.utils.DesignerInteractionHistory; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; -import com.fr.form.ui.container.WParameterLayout; import java.awt.*; @@ -193,8 +197,29 @@ public abstract class AccessDirection implements Direction { if (type != formEditor.getCursor().getType()) { // 设置当前形状 formEditor.setCursor(Cursor.getPredefinedCursor(type)); + + // 显示/改变Tooltip + showTooltip(formEditor); } } + + private void showTooltip(FormDesigner formEditor) { + // 显示拖拽改变组件尺寸相关的提示信息 + int cursorType = formEditor.getCursor().getType(); + if (Cursor.SW_RESIZE_CURSOR <= cursorType && cursorType <= Cursor.E_RESIZE_CURSOR) { + FormSelection selection = formEditor.getSelectionModel().getSelection(); + boolean canLockAspectRatioOnlyByShift = !selection.isCreatorAspectRatioLockedInAbsLayout(formEditor) && selection.isCreatorInAbsLayout(formEditor); + DesignerInteractionHistory history = DesignerInteractionHistory.getInstance(); + if (canLockAspectRatioOnlyByShift && !history.isHasShownShiftDragResizingTooltip()) { + formEditor.setToolTipText(getTooltip()); + history.setHasShownShiftDragResizingTooltip(true); + } + } + } + + public String getTooltip() { + return null; + } /** * 生成组件备用的bound diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/location/Bottom.java b/designer-form/src/main/java/com/fr/design/designer/beans/location/Bottom.java index 1cbfe1c41..0f51f3c88 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/location/Bottom.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/location/Bottom.java @@ -15,6 +15,12 @@ public class Bottom extends AccessDirection { Rectangle oldbounds) { current_bounds.height = sorption(0, oldbounds.height + dy + oldbounds.y, current_bounds, designer)[1] - oldbounds.y; + + if (designer.getStateModel().isAspectRatioLocked()) { + Rectangle backupBounds = designer.getSelectionModel().getSelection().getBackupBounds(); + current_bounds.width = (int) (backupBounds.width * current_bounds.height / backupBounds.height * 1.0); + } + return current_bounds; } @@ -23,6 +29,11 @@ public class Bottom extends AccessDirection { return Cursor.S_RESIZE_CURSOR; } + @Override + public String getTooltip() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Lock_Aspect_Ratio_Mouse_ToolTip"); + } + @Override public int getActual() { return Direction.BOTTOM; diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/location/Left.java b/designer-form/src/main/java/com/fr/design/designer/beans/location/Left.java index d78b08c03..3e773bf0e 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/location/Left.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/location/Left.java @@ -15,6 +15,12 @@ public class Left extends AccessDirection { Rectangle oldbounds) { current_bounds.x = sorption(oldbounds.x + dx, 0, current_bounds, designer)[0]; current_bounds.width = oldbounds.width - current_bounds.x + oldbounds.x; + + if (designer.getStateModel().isAspectRatioLocked()) { + Rectangle backupBounds = designer.getSelectionModel().getSelection().getBackupBounds(); + current_bounds.height = (int) (backupBounds.height * current_bounds.width / backupBounds.width * 1.0); + } + return current_bounds; } @@ -23,6 +29,11 @@ public class Left extends AccessDirection { return Cursor.W_RESIZE_CURSOR; } + @Override + public String getTooltip() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Lock_Aspect_Ratio_Mouse_ToolTip"); + } + @Override public int getActual() { return Direction.LEFT; diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/location/LeftBottom.java b/designer-form/src/main/java/com/fr/design/designer/beans/location/LeftBottom.java index 3c1a37241..a60b16585 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/location/LeftBottom.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/location/LeftBottom.java @@ -17,6 +17,21 @@ public class LeftBottom extends AccessDirection { current_bounds.x = xy[0]; current_bounds.width = oldbounds.width - current_bounds.x + oldbounds.x; current_bounds.height = xy[1] - oldbounds.y; + + if (designer.getStateModel().isAspectRatioLocked()) { + Rectangle backupBounds = designer.getSelectionModel().getSelection().getBackupBounds(); + double current_diagonal = Math.pow(current_bounds.width, 2) + Math.pow(current_bounds.height, 2); + double backup_diagonal = Math.pow(backupBounds.width, 2) + Math.pow(backupBounds.height, 2); + + int width = (int) (Math.sqrt((current_diagonal / backup_diagonal) * (Math.pow(backupBounds.width, 2)))); + int height = (int) (Math.sqrt((current_diagonal / backup_diagonal) * (Math.pow(backupBounds.height, 2)))); + + int currentRight = current_bounds.x + current_bounds.width; + current_bounds.width = width; + current_bounds.height = height; + current_bounds.x = currentRight - width; + } + return current_bounds; } @@ -25,6 +40,11 @@ public class LeftBottom extends AccessDirection { return Cursor.SW_RESIZE_CURSOR; } + @Override + public String getTooltip() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Lock_Aspect_Ratio_Mouse_ToolTip"); + } + @Override public int getActual() { return Direction.LEFT_BOTTOM; diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/location/LeftTop.java b/designer-form/src/main/java/com/fr/design/designer/beans/location/LeftTop.java index 7687f6136..159b317eb 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/location/LeftTop.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/location/LeftTop.java @@ -6,6 +6,7 @@ import java.awt.Rectangle; import com.fr.design.mainframe.FormDesigner; public class LeftTop extends AccessDirection { + public LeftTop() { } @@ -17,6 +18,23 @@ public class LeftTop extends AccessDirection { current_bounds.y = xy[1]; current_bounds.width = oldbounds.width - current_bounds.x + oldbounds.x; current_bounds.height = oldbounds.height - current_bounds.y + oldbounds.y; + + if (designer.getStateModel().isAspectRatioLocked()) { + Rectangle backupBounds = designer.getSelectionModel().getSelection().getBackupBounds(); + double current_diagonal = Math.pow(current_bounds.width, 2) + Math.pow(current_bounds.height, 2); + double backup_diagonal = Math.pow(backupBounds.width, 2) + Math.pow(backupBounds.height, 2); + + int width = (int) (Math.sqrt((current_diagonal / backup_diagonal) * (Math.pow(backupBounds.width, 2)))); + int height = (int) (Math.sqrt((current_diagonal / backup_diagonal) * (Math.pow(backupBounds.height, 2)))); + + int currentRight = current_bounds.x + current_bounds.width; + int currentBottom = current_bounds.y + current_bounds.height; + current_bounds.width = width; + current_bounds.height = height; + current_bounds.x = currentRight - width; + current_bounds.y = currentBottom - height; + } + return current_bounds; } @@ -25,6 +43,11 @@ public class LeftTop extends AccessDirection { return Cursor.NW_RESIZE_CURSOR; } + @Override + public String getTooltip() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Lock_Aspect_Ratio_Mouse_ToolTip"); + } + @Override public int getActual() { return Direction.LEFT_TOP; diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/location/Right.java b/designer-form/src/main/java/com/fr/design/designer/beans/location/Right.java index aa44a8fb3..deab920a2 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/location/Right.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/location/Right.java @@ -3,7 +3,9 @@ package com.fr.design.designer.beans.location; import java.awt.Cursor; import java.awt.Rectangle; +import com.fr.design.designer.creator.XCreator; import com.fr.design.mainframe.FormDesigner; +import com.fr.form.ui.Widget; public class Right extends AccessDirection { @@ -15,6 +17,12 @@ public class Right extends AccessDirection { Rectangle oldbounds) { current_bounds.width = sorption(oldbounds.x + dx + oldbounds.width, 0, current_bounds, designer)[0] - oldbounds.x; + + if (designer.getStateModel().isAspectRatioLocked()) { + Rectangle backupBounds = designer.getSelectionModel().getSelection().getBackupBounds(); + current_bounds.height = (int) (backupBounds.height * current_bounds.width / backupBounds.width * 1.0); + } + return current_bounds; } @@ -23,6 +31,11 @@ public class Right extends AccessDirection { return Cursor.E_RESIZE_CURSOR; } + @Override + public String getTooltip() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Lock_Aspect_Ratio_Mouse_ToolTip"); + } + @Override public int getActual() { return Direction.RIGHT; diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/location/RightBottom.java b/designer-form/src/main/java/com/fr/design/designer/beans/location/RightBottom.java index 6247ce3a1..99a013fe3 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/location/RightBottom.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/location/RightBottom.java @@ -16,6 +16,19 @@ public class RightBottom extends AccessDirection { int[] xy = sorption(oldbounds.x + dx + oldbounds.width, oldbounds.height + dy + oldbounds.y, current_bounds, designer); current_bounds.width = xy[0] - oldbounds.x; current_bounds.height = xy[1] - oldbounds.y; + + if (designer.getStateModel().isAspectRatioLocked()) { + Rectangle backupBounds = designer.getSelectionModel().getSelection().getBackupBounds(); + double current_diagonal = Math.pow(current_bounds.width, 2) + Math.pow(current_bounds.height, 2); + double backup_diagonal = Math.pow(backupBounds.width, 2) + Math.pow(backupBounds.height, 2); + + int width = (int) (Math.sqrt((current_diagonal / backup_diagonal) * (Math.pow(backupBounds.width, 2)))); + int height = (int) (Math.sqrt((current_diagonal / backup_diagonal) * (Math.pow(backupBounds.height, 2)))); + + current_bounds.width = width; + current_bounds.height = height; + } + return current_bounds; } @@ -24,6 +37,11 @@ public class RightBottom extends AccessDirection { return Cursor.SE_RESIZE_CURSOR; } + @Override + public String getTooltip() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Lock_Aspect_Ratio_Mouse_ToolTip"); + } + @Override public int getActual() { return Direction.RIGHT_BOTTOM; diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/location/RightTop.java b/designer-form/src/main/java/com/fr/design/designer/beans/location/RightTop.java index 3434e5d10..d858fc080 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/location/RightTop.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/location/RightTop.java @@ -16,6 +16,21 @@ public class RightTop extends AccessDirection { current_bounds.y = xy[1]; current_bounds.height = oldbounds.height - current_bounds.y + oldbounds.y; current_bounds.width = xy[0] - oldbounds.x; + + if (designer.getStateModel().isAspectRatioLocked()) { + Rectangle backupBounds = designer.getSelectionModel().getSelection().getBackupBounds(); + double current_diagonal = Math.pow(current_bounds.width, 2) + Math.pow(current_bounds.height, 2); + double backup_diagonal = Math.pow(backupBounds.width, 2) + Math.pow(backupBounds.height, 2); + + int width = (int) (Math.sqrt((current_diagonal / backup_diagonal) * (Math.pow(backupBounds.width, 2)))); + int height = (int) (Math.sqrt((current_diagonal / backup_diagonal) * (Math.pow(backupBounds.height, 2)))); + + int currentBottom = current_bounds.y + current_bounds.height; + current_bounds.width = width; + current_bounds.height = height; + current_bounds.y = currentBottom - height; + } + return current_bounds; } @@ -24,6 +39,11 @@ public class RightTop extends AccessDirection { return Cursor.NE_RESIZE_CURSOR; } + @Override + public String getTooltip() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Lock_Aspect_Ratio_Mouse_ToolTip"); + } + @Override public int getActual() { return Direction.RIGHT_TOP; diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/location/Top.java b/designer-form/src/main/java/com/fr/design/designer/beans/location/Top.java index 7f20213f2..5817e4541 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/location/Top.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/location/Top.java @@ -15,6 +15,12 @@ public class Top extends AccessDirection { Rectangle oldbounds) { current_bounds.y = sorption(0, dy + oldbounds.y, current_bounds, designer)[1]; current_bounds.height = oldbounds.height - current_bounds.y + oldbounds.y; + + if (designer.getStateModel().isAspectRatioLocked()) { + Rectangle backupBounds = designer.getSelectionModel().getSelection().getBackupBounds(); + current_bounds.width = (int) (backupBounds.width * current_bounds.height / backupBounds.height * 1.0); + } + return current_bounds; } @@ -23,6 +29,11 @@ public class Top extends AccessDirection { return Cursor.N_RESIZE_CURSOR; } + @Override + public String getTooltip() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Lock_Aspect_Ratio_Mouse_ToolTip"); + } + @Override public int getActual() { return Direction.TOP; diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/StateModel.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/StateModel.java index 85a328032..3b676921b 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/models/StateModel.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/StateModel.java @@ -15,6 +15,7 @@ import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWAbsoluteBodyLayout; import com.fr.design.designer.creator.XWAbsoluteLayout; import com.fr.design.mainframe.FormDesigner; +import com.fr.design.mainframe.FormSelection; import com.fr.design.mainframe.FormSelectionUtils; import com.fr.design.utils.ComponentUtils; @@ -55,6 +56,8 @@ public class StateModel { // 当前是否处于拖拽选择状态 private boolean selecting; private boolean dragging; + // 拖拽时需要保持组件尺寸比例 + private boolean aspectRatioLocked; private boolean addable; @@ -83,6 +86,10 @@ public class StateModel { return selecting; } + public boolean isAspectRatioLocked() { + return this.aspectRatioLocked; + } + /** * 是否能拖拽 * @@ -393,6 +400,7 @@ public class StateModel { * 重置model */ public void resetModel() { + aspectRatioLocked = false; dragging = false; selecting = false; } @@ -402,6 +410,7 @@ public class StateModel { */ public void reset() { driection = Location.outer; + aspectRatioLocked = false; dragging = false; selecting = false; } @@ -482,6 +491,10 @@ public class StateModel { } checkAddable(e); setDependLinePainter(e); + + FormSelection selection = this.selectionModel.getSelection(); + this.aspectRatioLocked = selection.isCreatorAspectRatioLockedInAbsLayout(designer) || + (this.selectionModel.getSelection().isCreatorInAbsLayout(designer) && e.isShiftDown()); driection.drag(getMouseXY(e).x - currentX, getMouseXY(e).y - currentY, designer); this.dragging = true; } @@ -508,6 +521,7 @@ public class StateModel { * @param e 鼠标事件 */ public void releaseDragging(MouseEvent e) { + this.aspectRatioLocked = false; this.dragging = false; if (addable) { adding(e.getX(), e.getY()); diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java index e4b5377ba..fc40b1d12 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java @@ -11,6 +11,7 @@ import com.fr.form.ui.Widget; import com.fr.form.ui.WidgetTitle; import com.fr.form.ui.WidgetValue; import com.fr.form.ui.container.WTitleLayout; +import com.fr.general.Background; import com.fr.general.ComparatorUtils; import com.fr.general.act.BorderPacker; import com.fr.general.act.TitlePacker; @@ -18,7 +19,11 @@ import com.fr.stable.Constants; import com.fr.stable.StringUtils; import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.LineBorder; import java.awt.*; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; /** * Created with IntelliJ IDEA. @@ -29,6 +34,7 @@ import java.awt.*; public class XBorderStyleWidgetCreator extends XWidgetCreator{ protected static final Dimension BORDER_PREFERRED_SIZE = new Dimension(250, 150); + protected Background background4Painting; // 设计器预览界面中绘制组件背景图 public XBorderStyleWidgetCreator(Widget widget, Dimension initSize) { super(widget, initSize); @@ -38,8 +44,17 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ this.setShareId(sharableAttrMark.getShareId()); } } - - /** + + public Background getBackground4Painting() { + return this.background4Painting; + } + + public void setBackground4Painting(Background background4Painting) { + this.background4Painting = background4Painting; + this.repaint(); + } + + /** * 返回容器对应的widget * @return 同上 */ @@ -47,25 +62,48 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ public AbstractBorderStyleWidget toData() { return (AbstractBorderStyleWidget) data; } - - protected void initStyle() { + + @Override + protected void addToWrapper(XLayoutContainer parentPanel, int width, int minHeight) { + super.addToWrapper(parentPanel, width, minHeight); + // REPORT-53175: 新创建的图表组件默认显示标题 since 10.0.18 + // 将当前对象添加到父容器后,初始化默认样式的效果 + initStyle(); + } + + protected void initStyle() { BorderPacker style = toData().getBorderStyle(); - initBorderStyle(); + initBorderAndBackgroundStyle(); if (ComparatorUtils.equals(style.getType(), LayoutBorderStyle.TITLE)) { initTitleStyle(style); } else { clearTitleWidget(); } + + // 编辑右侧栏组件样式面板后,重新调整组件/标题/边框的显示效果 + reshuffleBorderAndBackgroundPaintingEffectIfTitleExists(); } - // 边框默认值设为NONE,不然像scalelayout这种只用默认边框的会不显示边框 - protected void initBorderStyle() { + protected void initBorderAndBackgroundStyle() { BorderPacker style = toData().getBorderStyle(); - if (style != null && style.getBorder() != Constants.LINE_NONE) { - this.setBorder(new UIRoundedBorder(style.getBorder(), style.getColor(), style.getBorderRadius())); - } else { - this.setBorder(DEFALUTBORDER); + LineBorder DEFAULT_LINE_BORDER = (LineBorder) DEFALUTBORDER; + + // 边框默认值设为NONE,不然像scalelayout这种只用默认边框的会不显示边框 + Border border = DEFAULT_LINE_BORDER; + if (style != null) { + int radius = style.getBorderRadius(); // 不管有无边框线, 圆角裁剪总是生效 + if (style.getBorder() != Constants.LINE_NONE) { + // 设置了边框线 + border = new UIRoundedBorder(style.getBorder(), style.getColor(), radius); + } else { + // 为设置边框线 + border = new UIRoundedBorder(DEFAULT_LINE_BORDER.getLineColor(), DEFAULT_LINE_BORDER.getThickness(), radius); + } } + + this.setBorder(border); + + this.setBackground4Painting(style != null ? style.getBackground() : null); } private void clearTitleWidget() { @@ -121,6 +159,12 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ title.setFont(wTitle.getFrFont()); title.setTextalign(wTitle.getPosition()); title.setBackground(wTitle.getBackground()); + title.setBackgroundOpacity(wTitle.getBackgroundOpacity()); + + title.setInsetImage(wTitle.getInsetImage()); + title.setInsetImagePadding(wTitle.getInsetImagePadding()); + title.setInsetRelativeTextLeft(wTitle.isInsetRelativeTextLeft()); + title.setInsetRelativeTextRight(wTitle.isInsetRelativeTextRight()); } private WidgetValue getTitleValue(TitlePacker wTitle){ @@ -129,6 +173,75 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ return new WidgetValue(value); } + // 如果存在标题栏,则需要重新弄调整边框和背景的显示效果,使得边框和背景的视觉效果出现在包含组件和标题的整体区域上, + // 而不是组件和标题各自出现独立的边框和背景,同时如存在标题栏,则标题栏下方还应有底部边框,作为标题和内容的分界线 + protected void reshuffleBorderAndBackgroundPaintingEffectIfTitleExists() { + Container parent = this.getParent(); + if (parent instanceof XWTitleLayout) { + XWTitleLayout titleParent = (XWTitleLayout) parent; + if (parent.getComponentCount() > 1) { + XCreator titleCreator = titleParent.getTitleCreator(); + XCreator bodyXCreator = titleParent.getBodyCreator(); + + Border border = bodyXCreator.getBorder(); + + titleParent.setBorder(border); // 容器绘制完整边框 + bodyXCreator.setBorder(BorderFactory.createEmptyBorder()); // body不绘制边框 + titleCreator.setBorder(BorderFactory.createEmptyBorder()); // title绘制底部边框 + if (border instanceof LineBorder) { + Color color = ((LineBorder) border).getLineColor(); + int thickness = ((LineBorder) border).getThickness(); + titleCreator.setBorder(new BottomLineBorder(color, thickness)); + } + + if (bodyXCreator instanceof XBorderStyleWidgetCreator) { + XBorderStyleWidgetCreator styledBodyXCreator = (XBorderStyleWidgetCreator) bodyXCreator; + Background background4Painting = styledBodyXCreator.getBackground4Painting(); + + styledBodyXCreator.setBackground4Painting(null); // body不绘制背景 + titleParent.setBackground4Painting(background4Painting); // 容器绘制完整背景 + } + } + } + } + + + // 根据当前组件边框裁剪内容,如果当前组件存在圆角,则应当按圆角裁剪内容 + private void clipByRoundedBorder(Graphics2D g2d) { + Border currentBorder = getBorder(); + if (currentBorder instanceof UIRoundedBorder) { + int thickness = ((UIRoundedBorder) currentBorder).getThickness(); + int radius = ((UIRoundedBorder) currentBorder).getRoundedCorner(); + int currentClipX = 0; + int currentClipY = 0; + int currentClipWidth = getWidth(); + int currentClipHeight = getHeight(); + int currentClipRadius = Math.max(radius - thickness, 0); // 应沿着边框外围进行裁剪 + g2d.clip(new RoundRectangle2D.Double(currentClipX, currentClipY, currentClipWidth, currentClipHeight, currentClipRadius, currentClipRadius)); + } + } + + // 设计器预览界面中绘制组件背景效果 + private void paintBackground(Graphics2D g2d) { + Background background4Painting = getBackground4Painting(); + if (background4Painting != null) { + background4Painting.paint(g2d, new Rectangle2D.Double(0, 0, getWidth(), getHeight())); + } + } + + @Override + protected void paintComponent(Graphics g) { + this.paintBackground((Graphics2D) g); + super.paintComponent(g); + } + + @Override + public void paint(Graphics g) { + this.clipByRoundedBorder((Graphics2D) g); + super.paint(g); + paintBorder(g); + } + @Override protected String getIconName() { return StringUtils.EMPTY; @@ -155,8 +268,33 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ * data属性改变触发其他操作 * */ - public void firePropertyChange(){ + public void firePropertyChange() { } - + + // 适用于标题栏的底部边框 + public static class BottomLineBorder extends LineBorder { + + private BottomLineBorder(Color color, int thickness) { + super(color, thickness); + } + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + Graphics2D g2d = (Graphics2D)g; + + Color oldColor = g2d.getColor(); + Stroke oldStroke = g2d.getStroke(); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g2d.setColor(getLineColor()); + g2d.setStroke(new BasicStroke(getThickness())); + g2d.drawLine(0, height, width, height); + + g2d.setStroke(oldStroke); + g2d.setColor(oldColor); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + } + } } \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java b/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java index 682dcc4d4..bbd2f52d9 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java @@ -165,7 +165,7 @@ public class XChartEditor extends XBorderStyleWidgetCreator { @Override protected void initXCreatorProperties() { super.initXCreatorProperties(); - initBorderStyle(); + initBorderAndBackgroundStyle(); BaseChartCollection collection = ((BaseChartEditor) data).getChartCollection(); isRefreshing = true; ((MiddleChartComponent) designerEditor.getEditorTarget()).populate(collection); @@ -255,7 +255,7 @@ public class XChartEditor extends XBorderStyleWidgetCreator { * @param e 鼠标点击事件 */ public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e) { - if (this.isShareConfigButtonFocus()) { + if (this.isHelpBtnOnFocus()) { CoverReportPane.showShareConfig(((XCreator) this.getParent()).toData()); return; } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java index 01d53f850..80bf1b51d 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java @@ -11,6 +11,7 @@ import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.events.DesignerEditor; import com.fr.design.designer.beans.models.SelectionModel; +import com.fr.design.designer.ui.SelectedPopupDialog; import com.fr.design.fun.ShareWidgetUIProcessor; import com.fr.design.fun.WidgetPropertyUIProvider; import com.fr.design.gui.imenu.UIPopupMenu; @@ -67,7 +68,10 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo private int[] directions; private Rectangle backupBound; private String shareId = StringUtils.EMPTY;//如果组件是共享的会有这个属性 - private boolean isShareConfigButtonFocus = false;//焦点是否在帮助按钮上 + private boolean isHelpBtnOnFocus = false;//焦点是否在帮助按钮上 + // 当前组件是否处在选中状态 + private boolean selected; + private SelectedPopupDialog popup; private static final int SHORTS_SEPARATOR_POS = 4; // 弹出菜单分割的位置 public XCreator(Widget ob, Dimension initSize) { @@ -671,12 +675,12 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo * 焦点是否在帮助按钮上 * @return 焦点是否在帮助按钮上 */ - public boolean isShareConfigButtonFocus() { - return isShareConfigButtonFocus; + public boolean isHelpBtnOnFocus() { + return isHelpBtnOnFocus; } - public void setShareConfigButtonFocus(boolean shareConfigButtonFocus) { - isShareConfigButtonFocus = shareConfigButtonFocus; + public void setHelpBtnOnFocus(boolean isHelpBtnOnFocus) { + this.isHelpBtnOnFocus = isHelpBtnOnFocus; } @@ -692,7 +696,7 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo if (coverPanel != null) { coverPanel.setVisible(display); coverPanel.setPreferredSize(editor.getPreferredSize()); - coverPanel.setBounds(editor.getBounds()); + coverPanel.setBounds(new Rectangle(0, 0 , editor.getWidth(), editor.getHeight())); editor.repaint(); } } @@ -760,6 +764,23 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo GraphHelper.draw(g, bounds, Constants.LINE_MEDIUM); } + /** + * 选中时右侧展示小弹窗 + * + * @param designer + * @param bounds + */ + public void showSelectedPopup(FormDesigner designer, Rectangle bounds, boolean accept) { + if (popup == null) { + popup = new SelectedPopupDialog(this, designer); + } + int extraX = (int) ((bounds.x + bounds.width + SelectedPopupDialog.OFFSET_X) * designer.getScale()); + int extraY = (int) (bounds.y * designer.getScale()); + popup.setLocation(designer.getLocationOnScreen().x + designer.getPaintX() + extraX, designer.getLocationOnScreen().y + designer.getPaintY() + extraY); + popup.setVisible(selected && accept); + popup.setRelativeBounds(bounds); + } + /** * 创建右击弹出菜单 * @@ -797,5 +818,15 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo } + public boolean isSelected() { + return selected; + } + + public void setSelected(boolean selected) { + this.selected = selected; + if (popup != null && !selected) { + popup.setVisible(false); + } + } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java index 9c459e986..7ed22c52d 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java @@ -1,6 +1,7 @@ package com.fr.design.designer.creator; import com.fr.base.BaseUtils; +import com.fr.base.Releasable; import com.fr.design.ExtraDesignClassManager; import com.fr.design.designer.properties.mobile.ElementCasePropertyUI; import com.fr.design.form.util.XCreatorConstants; @@ -32,7 +33,7 @@ import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.util.Set; -public class XElementCase extends XBorderStyleWidgetCreator implements FormElementCaseContainerProvider { +public class XElementCase extends XBorderStyleWidgetCreator implements FormElementCaseContainerProvider , Releasable { private UILabel imageLable; private FormDesigner designer; private static BufferedImage DEFAULT_BACKGROUND; @@ -57,7 +58,7 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme super.initXCreatorProperties(); // 报表块初始化时要加载对应的borderStyle - initBorderStyle(); + initBorderAndBackgroundStyle(); } /** @@ -306,7 +307,7 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e) { super.respondClick(editingMouseListener, e); editingMouseListener.refreshTopXCreator(); - if (this.isShareConfigButtonFocus()) { + if (this.isHelpBtnOnFocus()) { CoverReportPane.showShareConfig(((XCreator) this.getParent()).toData()); } else { switchTab(e, editingMouseListener); @@ -352,4 +353,9 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme public boolean isSupportShared() { return true; } + + @Override + public void releaseResources() { + imageLable.setIcon(null); + } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XLabel.java b/designer-form/src/main/java/com/fr/design/designer/creator/XLabel.java index df2252c7a..154091a29 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XLabel.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XLabel.java @@ -5,6 +5,7 @@ package com.fr.design.designer.creator; import com.fr.base.BaseUtils; import com.fr.base.Style; +import com.fr.base.background.ImageBackground; import com.fr.design.border.UIRoundedBorder; import com.fr.design.form.util.FontTransformUtil; import com.fr.design.form.util.XCreatorConstants; @@ -17,6 +18,7 @@ import com.fr.design.mainframe.widget.renderer.LabelHorizontalAlignmentRenderer; import com.fr.form.ui.Label; import com.fr.form.ui.container.WParameterLayout; +import com.fr.general.Background; import com.fr.stable.ArrayUtils; import com.fr.stable.Constants; import com.fr.stable.core.PropertyChangeAdapter; @@ -94,10 +96,18 @@ public class XLabel extends XWidgetCreator { } if (label.getWidgetValue() != null) { Graphics2D g2d = (Graphics2D) g.create(); - BaseUtils.drawStringStyleInRotation(g2d, this.getWidth(), this.getHeight(), label.getWidgetValue() - .toString(), Style.getInstance(label.getFont()).deriveHorizontalAlignment(label.getTextalign()) + + Background inset = label.getInsetImage(); + Image insetImage = inset instanceof ImageBackground ? ((ImageBackground) inset).getImage() : null; + + BaseUtils.drawStringStyleInRotation(g2d, + this.getWidth(), this.getHeight(), + label.getWidgetValue().toString(), + Style.getInstance(label.getFont()) + .deriveHorizontalAlignment(label.getTextalign()) .deriveVerticalAlignment(label.isVerticalCenter() ? SwingConstants.CENTER : SwingConstants.TOP) .deriveTextStyle(label.isWrap() ? Style.TEXTSTYLE_WRAPTEXT : Style.TEXTSTYLE_SINGLELINE), + insetImage, label.getInsetImagePadding(), label.isInsetRelativeTextLeft(), label.isInsetRelativeTextRight(), FontTransformUtil.getDesignerFontResolution()); } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java b/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java index 9044d6c3c..50c5967c5 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java @@ -48,6 +48,8 @@ public abstract class XLayoutContainer extends XBorderStyleWidgetCreator impleme //鼠标移动到布局画出编辑层 protected boolean isMouseEnter = false; + private volatile boolean dragInAble; + public void setMouseEnter(boolean mouseEnter) { isMouseEnter = mouseEnter; } @@ -116,7 +118,7 @@ public abstract class XLayoutContainer extends XBorderStyleWidgetCreator impleme @Override protected void initXCreatorProperties() { super.initXCreatorProperties(); - initBorderStyle(); + initBorderAndBackgroundStyle(); this.initLayoutManager(); this.convert(); } @@ -577,4 +579,11 @@ public abstract class XLayoutContainer extends XBorderStyleWidgetCreator impleme return false; } + public boolean isDragInAble() { + return dragInAble; + } + + public void setDragInAble(boolean dragInAble) { + this.dragInAble = dragInAble; + } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XNameWidget.java b/designer-form/src/main/java/com/fr/design/designer/creator/XNameWidget.java index 0f78c5739..2cc20e111 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XNameWidget.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XNameWidget.java @@ -91,7 +91,6 @@ public class XNameWidget extends XWidgetCreator { if (editor != null) { this.setLayout(FRGUIPaneFactory.createBorderLayout()); add(editor, BorderLayout.CENTER); - this.setVisible(toData().isVisible()); } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteBodyLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteBodyLayout.java index a43ed0125..aa5612c09 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteBodyLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteBodyLayout.java @@ -106,7 +106,7 @@ public class XWAbsoluteBodyLayout extends XWAbsoluteLayout { @Override protected void initStyle() { - initBorderStyle(); + initBorderAndBackgroundStyle(); } /** diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java index 32273ca08..72bb2cb03 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java @@ -203,6 +203,10 @@ public class XWAbsoluteLayout extends XLayoutContainer { double percentH = ((double) backupBound.height / (double) currentBound.height); for (int index = 0, n = this.getComponentCount(); index < n; index++) { XCreator creator = (XCreator) this.getComponent(index); + if (creator.toData().isAspectRatioLocked()) { + double percent = Math.min(percentW, percentH); + percentW = percentH = percent; + } BoundsWidget wgt = (BoundsWidget) layout.getBoundsWidget(creator.toData()); // 用当前的显示大小计算后调正具体位置 Rectangle wgtBound = creator.getBounds(); @@ -467,7 +471,7 @@ public class XWAbsoluteLayout extends XLayoutContainer { * @param e 鼠标点击事件 */ public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e) { - if (this.isShareConfigButtonFocus()) { + if (this.isHelpBtnOnFocus()) { CoverReportPane.showShareConfig(this.toData()); return; } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java index bfa841a4a..ba864e607 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java @@ -10,10 +10,9 @@ import com.fr.design.fun.WidgetPropertyUIProvider; import com.fr.form.ui.Label; import com.fr.form.ui.Widget; import com.fr.form.ui.WidgetTitle; +import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; import com.fr.form.ui.container.WTitleLayout; import com.fr.general.ComparatorUtils; -import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; -import com.fr.stable.StringUtils; import java.awt.*; import java.awt.event.ContainerEvent; @@ -46,6 +45,17 @@ public class XWTitleLayout extends DedicateLayoutContainer { super(widget, initSize); } + @Override + protected void initXCreatorProperties() { + super.initXCreatorProperties(); + + // 初始化后(如打开旧模版),需要重新调整组件/标题/边框的显示效果 + XCreator xCreator = getBodyCreator(); + if (xCreator instanceof XBorderStyleWidgetCreator) { + ((XBorderStyleWidgetCreator) xCreator).reshuffleBorderAndBackgroundPaintingEffectIfTitleExists(); + } + } + /** * 初始化容器对应的布局 由于是只装一个需要保持原样高度的控件,布局设为absolute */ diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java index 1ff3f41c5..4fb422c0a 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java @@ -400,7 +400,7 @@ public class XWCardLayout extends XLayoutContainer { protected void initStyle() { BorderPacker style = toData().getBorderStyle(); initBorderTitleStyle(style); - initBorderStyle(); + initBorderAndBackgroundStyle(); clearOrShowTitleLayout(ComparatorUtils.equals(style.getType(), LayoutBorderStyle.TITLE)); } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java index 2d5b5ba91..992fa00cc 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java @@ -358,7 +358,7 @@ public class XWCardMainBorderLayout extends XWBorderLayout { */ @Override public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e){ - if (this.isShareConfigButtonFocus()) { + if (this.isHelpBtnOnFocus()) { CoverReportPane.showShareConfig(this.toData()); return; } @@ -447,4 +447,9 @@ public class XWCardMainBorderLayout extends XWBorderLayout { return true; } + @Override + public Dimension initEditorSize() { + return LARGEPREFERREDSIZE; + } + } diff --git a/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java b/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java new file mode 100644 index 000000000..b8133d3da --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java @@ -0,0 +1,191 @@ +package com.fr.design.designer.ui; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.CoverReportPane; +import com.fr.design.mainframe.EditingMouseListener; +import com.fr.design.mainframe.FormDesigner; +import com.fr.general.IOUtils; +import com.fr.stable.ArrayUtils; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import javax.swing.AbstractButton; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JToggleButton; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/7/8 + */ +public class PopupControlPanel extends JPanel { + + private static final int ARC_VALUE = 4; + private static final Color FILLED_COLOR = new Color(60, 63, 65); + private static final int V_GAP = 10; + private static final int H_GAP = 2; + + private Dimension defaultDimension = new Dimension(20, 60); + private Rectangle rectangle; + private final JButton editButton; + private final JButton settingButton; + private final JToggleButton toggleButton; + private final XCreator creator; + private final UILabel firstLabel; + private final UILabel secondLabel; + + public PopupControlPanel(XCreator creator, FormDesigner designer) { + if (creator.isShared()) { + defaultDimension = new Dimension(20, 85); + } + setLayout(getCustomLayout()); + this.creator = creator; + editButton = createNormalButton(IOUtils.readIcon("/com/fr/design/images/control/show_edit.png"), Toolkit.i18nText("Fine-Design_Form_Edit_Widget")); + editButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + int x = rectangle.x + rectangle.width / 2; + int y = rectangle.y + rectangle.height / 2; + XCreator childCreator = PopupControlPanel.this.creator.getEditingChildCreator(); + MouseListener[] listeners = designer.getMouseListeners(); + if (ArrayUtils.isNotEmpty(listeners) && listeners[0] instanceof EditingMouseListener) { + childCreator.respondClick(((EditingMouseListener) listeners[0]), new MouseEvent(childCreator, MouseEvent.MOUSE_CLICKED, e.getWhen(), e.getModifiers(), x, y, 2, false)); + } + } + }); + settingButton = createNormalButton(IOUtils.readIcon("/com/fr/design/images/control/show_setting.png"), Toolkit.i18nText("Fine-Design_Share_Help_Settings")); + + settingButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + CoverReportPane.showShareConfig(creator.toData()); + } + }); + toggleButton = new JToggleButton(IOUtils.readIcon("/com/fr/design/images/control/edit_lock.png")); + initButtonStyle(toggleButton); + toggleButton.setSelectedIcon(IOUtils.readIcon("com/fr/design/images/control/edit_unlock.png")); + toggleButton.setToolTipText(Toolkit.i18nText("Fine-Design_Form_Lock_Widget_Ratio")); + toggleButton.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + JToggleButton toggleBtn = (JToggleButton) e.getSource(); + String toolTipText = toggleBtn.isSelected() ? Toolkit.i18nText("Fine-Design_Form_UnLock_Widget_Ratio") : Toolkit.i18nText("Fine-Design_Form_Lock_Widget_Ratio"); + toggleBtn.setToolTipText(toolTipText); + } + }); + + firstLabel = createLabel(); + secondLabel = createLabel(); + + add(editButton); + add(toggleButton); + add(settingButton); + add(firstLabel); + add(secondLabel); + } + + protected LayoutManager getCustomLayout() { + return new LayoutManager() { + + @Override + public void removeLayoutComponent(Component comp) { + } + + @Override + public Dimension preferredLayoutSize(Container parent) { + return defaultDimension; + } + + @Override + public Dimension minimumLayoutSize(Container parent) { + return null; + } + + @Override + public void layoutContainer(Container parent) { + int width = parent.getPreferredSize().width; + int buttonWidth = editButton.getPreferredSize().width; + int buttonHeight = editButton.getPreferredSize().height; + int x = (width - buttonWidth) / 2; + editButton.setBounds(x, V_GAP, buttonWidth, buttonHeight); + firstLabel.setBounds(x, V_GAP + editButton.getHeight() + V_GAP / 2, buttonWidth, buttonHeight); + toggleButton.setBounds(x, V_GAP * 2 + editButton.getHeight(), buttonWidth, buttonHeight); + if (creator.isShared()) { + secondLabel.setBounds(x, V_GAP * 2 + editButton.getHeight() + toggleButton.getHeight() + V_GAP / 2, buttonWidth, buttonHeight); + settingButton.setBounds(x, V_GAP * 3 + editButton.getHeight() + toggleButton.getHeight(), buttonWidth, buttonHeight); + } + } + + @Override + public void addLayoutComponent(String name, Component comp) { + } + }; + } + + private JButton createNormalButton(Icon icon, String toolTipText) { + JButton button = new JButton(icon); + initButtonStyle(button); + button.setToolTipText(toolTipText); + return button; + } + + private void initButtonStyle(AbstractButton button) { + button.setBorderPainted(false); + button.setBorder(null); + button.setMargin(new Insets(0, 0, 0, 0)); + button.setContentAreaFilled(false); + } + + private UILabel createLabel() { + return new UILabel() { + @Override + public void paint(Graphics g) { + super.paint(g); + Graphics2D g2d = (Graphics2D) g; + g2d.setColor(Color.WHITE); + g2d.drawLine(H_GAP, 0, toggleButton.getWidth() - H_GAP, 0); + + } + }; + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + int w = this.getWidth(); + int h = this.getHeight(); + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setColor(FILLED_COLOR); + g2d.fillRoundRect(0, 0, w - 1, h - 1, ARC_VALUE, ARC_VALUE); + g2d.setColor(Color.WHITE); + g2d.drawRoundRect(0, 0, w - 1, h - 1, ARC_VALUE, ARC_VALUE); + } + + public Dimension getDefaultDimension() { + return defaultDimension; + } + + public void setRelativeBounds(Rectangle rectangle) { + this.rectangle = rectangle; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/ui/SelectedPopupDialog.java b/designer-form/src/main/java/com/fr/design/designer/ui/SelectedPopupDialog.java new file mode 100644 index 000000000..e7de92679 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/ui/SelectedPopupDialog.java @@ -0,0 +1,36 @@ +package com.fr.design.designer.ui; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.FormDesigner; +import java.awt.Rectangle; +import javax.swing.JDialog; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/7/09 + */ +public class SelectedPopupDialog extends JDialog { + + /** + * 弹窗的相对组件的偏移 + */ + public static final int OFFSET_X = 5; + + private final PopupControlPanel controlPanel; + + public SelectedPopupDialog(XCreator creator, FormDesigner designer) { + super(DesignerContext.getDesignerFrame()); + this.setUndecorated(true); + this.setModal(false); + controlPanel = new PopupControlPanel(creator, designer); + this.getContentPane().add(controlPanel); + this.setSize(controlPanel.getDefaultDimension()); + } + + public void setRelativeBounds(Rectangle rectangle) { + this.controlPanel.setRelativeBounds(rectangle); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java b/designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java index 834b6b4a8..2a67f61ae 100644 --- a/designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java +++ b/designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java @@ -2,7 +2,6 @@ package com.fr.design.gui.controlpane; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.properties.EventPropertyTable; -import com.fr.design.file.Releasable; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.FormDesigner; import com.fr.design.widget.EventCreator; @@ -14,7 +13,7 @@ import com.fr.stable.Nameable; /** * Created by kerry on 5/17/21 */ -public class EventPropertyPane extends UIListGroupControlPane implements Releasable { +public class EventPropertyPane extends UIListGroupControlPane { private XCreator creator; private FormDesigner designer; @@ -25,12 +24,6 @@ public class EventPropertyPane extends UIListGroupControlPane implements Releasa this.designer = designer; } - @Override - public void releaseResources() { - creator = null; - designer = null; - this.removeAll(); - } /** * 刷新 diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/BorderLineAndImagePane.java b/designer-form/src/main/java/com/fr/design/gui/xpane/BorderLineAndImagePane.java new file mode 100644 index 000000000..27c045459 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/gui/xpane/BorderLineAndImagePane.java @@ -0,0 +1,623 @@ +package com.fr.design.gui.xpane; + +import com.fr.base.GraphHelper; +import com.fr.base.Style; +import com.fr.base.Utils; +import com.fr.base.background.ImageBackground; +import com.fr.base.background.ImageFileBackground; +import com.fr.design.border.UIRoundedBorder; +import com.fr.design.constants.UIConstants; +import com.fr.design.designer.IntervalConstants; +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.BasicPane; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.event.UIObserver; +import com.fr.design.event.UIObserverListener; +import com.fr.design.gui.frpane.ImgChooseWrapper; +import com.fr.design.gui.frpane.UIPercentDragPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIButtonUI; +import com.fr.design.gui.ibutton.UIColorButton; +import com.fr.design.gui.icombobox.LineComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.backgroundpane.ImagePreviewPane; +import com.fr.design.style.background.image.ImageFileChooser; +import com.fr.env.utils.DesignerInteractionHistory; +import com.fr.form.ui.LayoutBorderStyle; +import com.fr.general.Background; +import com.fr.general.IOUtils; +import com.fr.stable.Constants; +import com.fr.stable.GraphDrawHelper; +import com.fr.stable.ProjectLibrary; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.project.ProjectConstants; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.basic.BasicButtonUI; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * @author Starryi + * @version 10.0.18 + * Created by Starryi on 2021/7/2 + * + * 可配置图片类型边框的样式设置面板 + */ +public class BorderLineAndImagePane extends JPanel implements UIObserver { + private final int SETTING_LABEL_WIDTH = LayoutStylePane.SETTING_LABEL_WIDTH; + private final Style DEFAULT_IMAGE_LAYOUT_STYLE = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_DEFAULT); + private final String TWEAK_NINE_POINT_HELP_URL = ""; + + private UIObserverListener uiObserverListener; + + private BorderLineAndImageComboBox borderLineCombo; + private UIColorButton borderColorPane; + private ImagePreviewPane imagePreviewPane; + private UIButton chooseImageButton; + private UIButton tweakNinePointHelpButton; + private UIButton tweakNinePointButton; + private UIPercentDragPane borderImageOpacityPane; + + private NinePointImageTweakDialogPane tweakPane; + private ImageFileChooser imageFileChooser; + + private int ninePointLeft = -1; + private int ninePointTop = -1; + private int ninePointRight = -1; + private int ninePointBottom = -1; + + public BorderLineAndImagePane() { + this.initComponents(); + this.initLayout(); + } + + private void initComponents() { + borderLineCombo = new BorderLineAndImageComboBox(); + borderColorPane = new UIColorButton(null) {{ + setUI(createButtonUI(this)); + set4ToolbarButton(); + }}; + imagePreviewPane = new ImagePreviewPane() {{ + setImageStyle(Style.DEFAULT_STYLE); + }}; + chooseImageButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Image_Select_Picture")); + + tweakNinePointHelpButton = new UIButton(IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_border_image_help.png")); + tweakNinePointHelpButton.setUI(new BasicButtonUI()); + tweakNinePointHelpButton.setBorderPainted(false); + tweakNinePointHelpButton.setBorder(null); + tweakNinePointHelpButton.setContentAreaFilled(false); + tweakNinePointHelpButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Desktop desktop = Desktop.getDesktop(); + try { + desktop.browse(new URI(TWEAK_NINE_POINT_HELP_URL)); + } catch (IOException | URISyntaxException ioException) { + ioException.printStackTrace(); + } + } + }); + + tweakNinePointButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Border_Image_Config_Nine_Point_Fill")); + borderImageOpacityPane = new UIPercentDragPane(); + } + + private JPanel createBorderLineComposedPane() { + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] rowSize = {p}; + double[] columnSize = {SETTING_LABEL_WIDTH, f}; + + return TableLayoutHelper.createGapTableLayoutPane( + new JComponent[][]{{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Border_Line")), this.borderLineCombo}}, + rowSize, columnSize, IntervalConstants.INTERVAL_L1, 0); + } + + private JPanel createBorderColorComposedPane() { + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] rowSize = {p}; + double[] columnSize = {SETTING_LABEL_WIDTH, f}; + + return TableLayoutHelper.createGapTableLayoutPane( + new JComponent[][]{{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Border_Color")), this.borderColorPane}}, + rowSize, columnSize, IntervalConstants.INTERVAL_L1, 0); + } + + private JPanel createBorderImageComposePane() { + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] rowSize = {p, p, p}; + double[] columnSize = {SETTING_LABEL_WIDTH, f}; + + JPanel borderedImagePreviewPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + borderedImagePreviewPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, 5)); + borderedImagePreviewPane.setPreferredSize(new Dimension(145, 145)); + borderedImagePreviewPane.add(imagePreviewPane, BorderLayout.CENTER); + + JPanel tweakNinePointComposedPane = new JPanel(); + tweakNinePointComposedPane.setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0)); + tweakNinePointButton.setPreferredSize(new Dimension(145, 16)); + tweakNinePointComposedPane.add(tweakNinePointHelpButton); + tweakNinePointComposedPane.add(tweakNinePointButton); + + return TableLayoutHelper.createGapTableLayoutPane( + new JComponent[][]{ + {null, borderedImagePreviewPane}, + {null, chooseImageButton}, + {tweakNinePointComposedPane, null}, + {null, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Alpha"))}, + {null, this.borderImageOpacityPane} + }, + rowSize, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); + } + + private void initImageFileChooserIfNotExist() { + if (imageFileChooser == null) { + imageFileChooser = new ImageFileChooser(); + imageFileChooser.setMultiSelectionEnabled(false); + } + } + + private void initImageFileChooserDirectory() { + DesignerInteractionHistory history = DesignerInteractionHistory.getInstance(); + String lastUsedBorderImageDirPath = history.getLastSelectedBorderImageDir(); + File lastUsedBorderImageDir = StringUtils.isNotEmpty(lastUsedBorderImageDirPath) ? new File(lastUsedBorderImageDirPath) : null; + + File inbuiltBorderImagesDir = new File(StableUtils.pathJoin(ProjectLibrary.getInstance().getLibHome(), ProjectConstants.ASSETS_NAME, "border_images")); + + if (lastUsedBorderImageDir!= null && lastUsedBorderImageDir.exists()) { + imageFileChooser.setCurrentDirectory(lastUsedBorderImageDir); + } else if (inbuiltBorderImagesDir.exists()) { + imageFileChooser.setCurrentDirectory(inbuiltBorderImagesDir); + } + } + + protected void initNinePointTweakPaneIfNotExist() { + if (tweakPane == null) { + tweakPane = new NinePointImageTweakDialogPane(); + } + } + + private void initLayout() { + this.setLayout(new BorderLayout(0, IntervalConstants.INTERVAL_L1)); + + this.add(this.createBorderLineComposedPane(), BorderLayout.NORTH, 0); + this.add(this.createBorderColorComposedPane(), BorderLayout.CENTER, 1); + this.add(this.createBorderImageComposePane(), BorderLayout.SOUTH, 2); + + getComponent(1).setVisible(false); + getComponent(2).setVisible(false); + + this.borderLineCombo.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + getComponent(1).setVisible(borderLineCombo.isSelectedBorderLine()); + getComponent(2).setVisible(borderLineCombo.isSelectedBorderImage()); + + if (!borderLineCombo.isSelectedBorderLine()) { + borderColorPane.setColor(Color.BLACK); + } + if (!borderLineCombo.isSelectedBorderImage()) { + imagePreviewPane.setImageWithSuffix(null); + } + + fireStateChanged(); + } + }); + this.chooseImageButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + initImageFileChooserIfNotExist(); + initImageFileChooserDirectory(); + int returnVal = imageFileChooser.showOpenDialog(DesignerContext.getDesignerFrame()); + + if (returnVal == JFileChooser.APPROVE_OPTION) { + DesignerInteractionHistory history = DesignerInteractionHistory.getInstance(); + File selectedDirectory = imageFileChooser.getSelectedFile().getParentFile(); + history.setLastSelectedBorderImageDir(selectedDirectory.getPath()); + } + + ImgChooseWrapper.getInstance(imagePreviewPane, imageFileChooser, DEFAULT_IMAGE_LAYOUT_STYLE, new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + Image image = imagePreviewPane.getImage(); + ninePointLeft = ninePointRight = (image != null ? image.getWidth(null) / 3 : -1); + ninePointTop = ninePointBottom = (image != null ? image.getHeight(null) / 3 : -1); + borderImageOpacityPane.populateBean(1.0); + + fireStateChanged(); + } + }).dealWithImageFile(returnVal); + } + }); + this.tweakNinePointButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + initNinePointTweakPaneIfNotExist(); + + if (imagePreviewPane.getImage() != null) { + BasicDialog dialog = tweakPane.showWindow(SwingUtilities.getWindowAncestor(BorderLineAndImagePane.this)); + dialog.addDialogActionListener(new DialogActionAdapter() { + @Override + public void doOk() { + fireStateChanged(); + } + }); + dialog.setVisible(true); + } + } + }); + } + + public void populateBean(LayoutBorderStyle style) { + int borderLine = style.getBorder(); + Color borderColor = style.getColor(); + + this.borderLineCombo.setSelectedLineStyle(borderLine); + this.borderColorPane.setColor(borderColor); + + Background borderImage = style.getBorderImage(); + if (borderImage instanceof ImageBackground) { + // 图片类型边框 + Image image = ((ImageBackground) borderImage).getImage(); + int[] ninePoint = ((ImageBackground) borderImage).getNinePoint(); + + if (image != null) { + this.borderLineCombo.selectBorderImage(); + this.imagePreviewPane.setImageWithSuffix(((ImageBackground) borderImage).getImageWithSuffix()); + this.borderImageOpacityPane.populateBean(style.getBorderImageOpacity()); + if (ninePoint != null && ninePoint.length == 4 && ninePoint[0] > 0 && ninePoint[1] > 0 && ninePoint[2] > 0 && ninePoint[3] > 0) { + ninePointLeft = ninePoint[0]; + ninePointTop = ninePoint[1]; + ninePointRight = ninePoint[2]; + ninePointBottom = ninePoint[3]; + } else { + ninePointLeft = ninePointRight = image.getWidth(null) / 3; + ninePointTop = ninePointBottom = image.getHeight(null) / 3; + } + + getComponent(1).setVisible(false); + getComponent(2).setVisible(true); + + return; + } + } + + if (borderLine == Constants.LINE_NONE) { + getComponent(1).setVisible(false); + getComponent(2).setVisible(false); + return; + } else { + getComponent(1).setVisible(true); + getComponent(2).setVisible(false); + } + + this.borderLineCombo.setSelectedLineStyle(style.getBorder()); + this.borderColorPane.setColor(style.getColor()); + } + + public void updateBean(LayoutBorderStyle style) { + + style.setBorder(this.borderLineCombo.getSelectedLineStyle()); + style.setColor(this.borderColorPane.getColor()); + style.setBorderImage(null); + + if (this.borderLineCombo.isSelectedBorderImage()) { + Image image = this.imagePreviewPane.getImage(); + if (image != null) { + ImageBackground newImageBackground = new ImageFileBackground(this.imagePreviewPane.getImageWithSuffix(), Constants.IMAGE_EXTEND); + newImageBackground.setNinePoint(new int[] { ninePointLeft, ninePointTop, ninePointRight, ninePointBottom }); + style.setBorderImage(newImageBackground); + style.setBorderImageOpacity((float)borderImageOpacityPane.updateBean()); + } + } + } + + private void fireStateChanged() { + if (uiObserverListener != null) { + uiObserverListener.doChange(); + } + } + + @Override + public void registerChangeListener(UIObserverListener listener) { + this.uiObserverListener = listener; + } + + @Override + public boolean shouldResponseChangeListener() { + return true; + } + + protected UIButtonUI createButtonUI(final UIColorButton uiColorButton) { + return new UIButtonUI() { + + public void paint(Graphics g, JComponent c) { + UIButton b = (UIButton) c; + g.setColor(Color.black); + GraphHelper.draw(g, new RoundRectangle2D.Double(1, 1, b.getWidth() - 2, b.getHeight() - 2, 0, 0), 1); + + if (b.getModel().isEnabled()) { + g.setColor(uiColorButton.getColor()); + } else { + g.setColor(new Color(Utils.filterRGB(uiColorButton.getColor().getRGB(), 50))); + } + g.fillRect(2, 2, b.getWidth() - 3, b.getHeight() - 3); + } + }; + } + + protected static class BorderLineAndImageComboBox extends LineComboBox { + public static final int LINE_PICTURE = -1; + public final static int[] BORDER_LINE_STYLE_ARRAY = new int[] { + Constants.LINE_NONE, + LINE_PICTURE, + Constants.LINE_THIN, //1px + Constants.LINE_MEDIUM, //2px + Constants.LINE_THICK, //3px + }; + + public BorderLineAndImageComboBox() { + super(BORDER_LINE_STYLE_ARRAY); + } + + @Override + protected String toStringFromStyle(int style) { + if (style == LINE_PICTURE) { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Border_Image"); + } + return super.toStringFromStyle(style); + } + + public boolean isSelectedBorderLine() { + return getSelectedIndex() > 1; + } + + public boolean isSelectedBorderImage() { + return getSelectedIndex() == 1; + } + + public void selectBorderImage() { + this.setSelectedIndex(1); + } + } + + private class NinePointImageTweakDialogPane extends BasicPane { + private final NinePointLinePreviewPane previewPane = new NinePointLinePreviewPane(); + + public NinePointImageTweakDialogPane() { + this.initComponents(); + } + + private void initComponents() { + setLayout(new BorderLayout()); + setBorder(BorderFactory.createTitledBorder(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Border_Image_Config_Nine_Point_Fill_Preview"))); + + JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane(); + content.setBorder(BorderFactory.createEmptyBorder( + IntervalConstants.INTERVAL_W1, + IntervalConstants.INTERVAL_W1, + IntervalConstants.INTERVAL_W1, + IntervalConstants.INTERVAL_W1)); + content.add(previewPane); + previewPane.setPreferredSize(new Dimension(611, 457)); + + add(content, BorderLayout.CENTER); + } + + @Override + protected String title4PopupWindow() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Border_Image_Config_Nine_Point_Fill"); + } + } + + private class NinePointLinePreviewPane extends JPanel implements MouseMotionListener, MouseListener { + private final BufferedImage transparentImage = IOUtils.readImage("/com/fr/design/images/transparent_background.jpg"); + + public final Color PATCH_COLOR = new Color(0, 0, 0, 38); + public final Color DIVIDER_COLOR = new Color(250, 250, 250); + public final Color TEXT_COLOR = Color.WHITE; + public final int PADDING = 15; + + private int imgWidth; + private int imgHeight; + private int scaleImgWidth; + private int scaleImgHeight; + private int scaleImgX; + private int scaleImgY; + private double scale = 1.0; + + public NinePointLinePreviewPane() { + this.addMouseMotionListener(this); + this.addMouseListener(this); + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + + Graphics2D g2d = (Graphics2D) g; + g2d.drawImage(transparentImage, 0, 0, getWidth(), getHeight(), null); + + Image image = imagePreviewPane.getImage(); + + imgWidth = image.getWidth(null); + imgHeight = image.getHeight(null); + int autoFixAreaWidth = getWidth() - 2 * PADDING; + int autoFixAreaHeight = getHeight() - 2 * PADDING; + int autoFixAreaX = PADDING; + int autoFixAreaY = PADDING; + + if (imgWidth / imgHeight > autoFixAreaWidth / autoFixAreaHeight) { + scaleImgWidth = autoFixAreaWidth; + scaleImgHeight = (int) (1.0F * scaleImgWidth * imgHeight / imgWidth); + scaleImgX = autoFixAreaX; + scaleImgY = (autoFixAreaHeight - scaleImgHeight) / 2 + autoFixAreaY; // 垂直居中 + scale = 1.0 * scaleImgWidth / imgWidth; + } else { + scaleImgHeight = autoFixAreaHeight; + scaleImgWidth = (int) (1.0F * scaleImgHeight * imgWidth / imgHeight); + scaleImgX = (autoFixAreaWidth - scaleImgWidth) / 2 + autoFixAreaX; // 水平居中 + scaleImgY = autoFixAreaY; + scale = 1.0 * scaleImgHeight / imgHeight; + } + + g2d.drawImage(image, scaleImgX, scaleImgY, scaleImgWidth, scaleImgHeight, null); + + int scaleLeft = (int) (ninePointLeft * scale); + int scaleTop = (int) (ninePointTop * scale); + int scaleRight = (int) (ninePointRight * scale); + int scaleBottom = (int) (ninePointBottom * scale); + + g2d.setColor(PATCH_COLOR); + // draw horizontal patch + GraphDrawHelper.fillRect(g2d, 0, scaleImgY + scaleTop, getWidth(), scaleImgHeight - scaleTop - scaleBottom); + // draw vertical patch + GraphDrawHelper.fillRect(g2d, scaleImgX + scaleLeft, 0,scaleImgWidth - scaleLeft - scaleRight, getHeight()); + + g2d.setColor(DIVIDER_COLOR); + // draw top divider + GraphDrawHelper.drawLine(g2d, 0, scaleImgY + scaleTop, getWidth(), scaleImgY + scaleTop); + // draw bottom divider + GraphDrawHelper.drawLine(g2d, 0, scaleImgY + scaleImgHeight - scaleBottom, getWidth(), scaleImgY + scaleImgHeight - scaleBottom); + // draw left divider + GraphDrawHelper.drawLine(g2d, scaleImgX + scaleLeft, 0, scaleImgX + scaleLeft, getHeight()); + // draw right divider + GraphDrawHelper.drawLine(g2d, scaleImgX + scaleImgWidth - scaleRight, 0, scaleImgX + scaleImgWidth - scaleRight, getHeight()); + + g2d.setColor(TEXT_COLOR); + // draw nine point info + GraphDrawHelper.drawString(g2d, Integer.toString(ninePointTop), scaleImgX + (scaleImgWidth + scaleLeft - scaleRight) / 2.0, (scaleImgY + scaleTop) / 2.0); + GraphDrawHelper.drawString(g2d, Integer.toString(ninePointBottom), scaleImgX + scaleLeft + (scaleImgWidth - scaleLeft - scaleRight) / 2.0, scaleImgY + scaleImgHeight - (scaleBottom - PADDING) / 2.0); + GraphDrawHelper.drawString(g2d, Integer.toString(ninePointLeft), (scaleImgX + scaleLeft) / 2.0, scaleImgY + (scaleImgHeight + scaleTop - scaleBottom) / 2.0); + GraphDrawHelper.drawString(g2d, Integer.toString(ninePointRight), scaleImgX + scaleImgWidth - (scaleRight - PADDING) / 2.0, scaleImgY + (scaleImgHeight + scaleTop - scaleBottom) / 2.0); + } + + @Override + public void mouseDragged(MouseEvent e) { + int x = e.getX(); + int y = e.getY(); + + int cursorType = getCursor().getType(); + + switch (cursorType) { + case Cursor.W_RESIZE_CURSOR: { + int nextLeft = (int) ((x - scaleImgX) / scale); + if (1 <= nextLeft && nextLeft < imgWidth - ninePointRight) { + ninePointLeft = nextLeft; + repaint(); + } + return; + } + case Cursor.E_RESIZE_CURSOR: { + int nextRight = (int) ((scaleImgX + scaleImgWidth - x) / scale); + if (1 <= nextRight && nextRight < imgWidth - ninePointLeft) { + ninePointRight = nextRight; + repaint(); + } + return; + } + case Cursor.N_RESIZE_CURSOR: { + int nextTop = (int) ((y - scaleImgY) / scale); + if (1 <= nextTop && nextTop < imgHeight - ninePointBottom) { + ninePointTop = nextTop; + repaint(); + } + return; + } + case Cursor.S_RESIZE_CURSOR: { + int nextBottom = (int) ((scaleImgY + scaleImgHeight - y) / scale); + if (1 <= nextBottom && nextBottom < imgHeight - ninePointTop) { + ninePointBottom = nextBottom; + repaint(); + } + } + } + } + + @Override + public void mouseMoved(MouseEvent e) { + boolean needRepaint; + + int x = e.getX(); + int y = e.getY(); + + double scaleLeft = ninePointLeft * scale; + double scaleTop = ninePointTop * scale; + double scaleRight = ninePointRight * scale; + double scaleBottom = ninePointBottom * scale; + + // determine cursor + int cursorType = Cursor.DEFAULT_CURSOR; + + boolean hoveringLeftDivider = Math.abs(x - (scaleImgX + scaleLeft)) < 2; + boolean hoveringRightDivider = Math.abs(x - (scaleImgX + scaleImgWidth - scaleRight)) < 2; + boolean hoveringTopDivider = Math.abs(y - (scaleImgY + scaleTop)) < 2; + boolean hoveringBottomDivider = Math.abs(y - (scaleImgY + scaleImgHeight - scaleBottom)) < 2; + + if (hoveringLeftDivider) { + cursorType = Cursor.W_RESIZE_CURSOR; + } else if (hoveringRightDivider) { + cursorType = Cursor.E_RESIZE_CURSOR; + } else if (hoveringTopDivider) { + cursorType = Cursor.N_RESIZE_CURSOR; + } else if (hoveringBottomDivider) { + cursorType = Cursor.S_RESIZE_CURSOR; + } + + needRepaint = getCursor().getType() != cursorType; + this.setCursor(Cursor.getPredefinedCursor(cursorType)); + + if (needRepaint) { + repaint(); + } + } + + @Override + public void mouseClicked(MouseEvent e) { + + } + + @Override + public void mousePressed(MouseEvent e) { + + } + + @Override + public void mouseReleased(MouseEvent e) { + this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + + repaint(); + } + + @Override + public void mouseEntered(MouseEvent e) { + + } + + @Override + public void mouseExited(MouseEvent e) { + + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/CardTagLayoutStylePane.java b/designer-form/src/main/java/com/fr/design/gui/xpane/CardTagLayoutStylePane.java new file mode 100644 index 000000000..5e6f7c06c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/gui/xpane/CardTagLayoutStylePane.java @@ -0,0 +1,27 @@ +/* + * Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved. + */ +package com.fr.design.gui.xpane; + +import com.fr.form.ui.LayoutBorderStyle; + +import javax.swing.*; + +/** + * CardTagLayoutBorderPane Pane. + */ +public class CardTagLayoutStylePane extends LayoutStylePane { + + @Override + protected JPanel createTitleStylePane(){ + return null; + } + + @Override + public void updateTitle(LayoutBorderStyle style) { + + } + + @Override + protected void populateTitle() { } +} diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutStylePane.java b/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutStylePane.java new file mode 100644 index 000000000..ee1de8f7e --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutStylePane.java @@ -0,0 +1,510 @@ +package com.fr.design.gui.xpane; + +import com.fr.base.GraphHelper; +import com.fr.base.Utils; +import com.fr.base.svg.IconUtils; +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.constants.UIConstants; +import com.fr.design.designer.IntervalConstants; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.formula.TinyFormulaPane; +import com.fr.design.gui.frpane.UIPercentDragPane; +import com.fr.design.gui.ibutton.UIButtonGroup; +import com.fr.design.gui.ibutton.UIColorButton; +import com.fr.design.gui.ibutton.UIToggleButton; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.icombobox.LineComboBox; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.ispinner.UISpinner; +import com.fr.design.gui.style.BackgroundSpecialPane; +import com.fr.design.gui.style.FRFontPane; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.JForm; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.backgroundpane.GradientBackgroundQuickPane; +import com.fr.form.ui.LayoutBorderStyle; +import com.fr.form.ui.WidgetTitle; +import com.fr.general.Background; +import com.fr.general.FRFont; +import com.fr.general.IOUtils; +import com.fr.general.act.TitlePacker; +import com.fr.stable.Constants; + +import javax.swing.*; +import javax.swing.border.LineBorder; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; + +/** + * @author Starryi + * @version 10.0.18 + * Created by Starryi on 2021/6/25 + * + * 可配置图片类型边框的样式设置面板 + */ +public class LayoutStylePane extends BasicBeanPane { + public static final String[] BORDER_STYLE = new String[]{ + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Common"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Shadow") + }; + private static final Dimension BUTTON_SIZE = new Dimension(20, 20); + public static final int SETTING_LABEL_WIDTH = 60; + + protected LayoutBorderStyle style = new LayoutBorderStyle(); + + //渲染风格:有无阴影 + protected UIComboBox borderStyleCombo; + // 含图片类型边框的边框配置面板(图片类型边框 + 阴影时存在默认的阴影颜色) + protected BorderLineAndImagePane borderLineAndImagePane; + //边框圆角或圆角裁剪 + protected UISpinner cornerSpinner; + //主体背景 + protected BackgroundSpecialPane backgroundPane; + //主体背景透明度 + protected UIPercentDragPane backgroundOpacityPane; + + // 标题可见 + protected UICheckBox titleVisibleCheckbox; + //标题文字内容 + protected TinyFormulaPane titleTextPane; + //标题字体格式 + protected UIComboBox titleFontFamilyComboBox; + //标题字体大小 + protected UIComboBox titleFontSizeComboBox; + //标题字体颜色 + protected UIColorButton titleFontColorSelectPane; + //标题字体特殊效果:粗体、斜体、下划线 + private UIToggleButton titleFontBoldButton; + private UIToggleButton titleFontItalicButton; + private UIToggleButton titleFontUnderlineButton; + private LineComboBox titleFontUnderlineCombo; + // 标题图文混排 + protected TitleInsetImagePane titleInsetImagePane; + //对齐方式 + protected UIButtonGroup titleAlignPane; + //标题整体背景 + protected BackgroundSpecialPane titleBackgroundPane; + //标题背景透明度 + protected UIPercentDragPane titleBackgroundOpacityPane; + + public LayoutStylePane() { + this.initLayout(); + } + + protected void initLayout() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + boolean currentIsRootLayout = currentEditingTemplate != null && !currentEditingTemplate.isJWorkBook() && ((JForm)currentEditingTemplate).isSelectRootPane(); + + JPanel titlePane = createTitleStylePane(); + if (titlePane != null) { + container.add(titlePane, BorderLayout.NORTH); + if (currentIsRootLayout) { + titlePane.setVisible(false); + } + } + + //界面上表单主体只有背景和透明度可以设置 + JPanel mainStylePane = currentIsRootLayout ? createMainStylePane4RootLayout() : createMainStylePane4WidgetLayout(); + if (mainStylePane != null) { + container.add(mainStylePane, BorderLayout.CENTER); + } + + this.add(container, BorderLayout.CENTER); + } + + protected void initMainComponents() { + borderStyleCombo = new UIComboBox(BORDER_STYLE); + borderLineAndImagePane = new BorderLineAndImagePane(); + cornerSpinner = new UISpinner(0,1000,1,0); + backgroundPane = new LayoutBackgroundSpecialPane(); + backgroundOpacityPane = new UIPercentDragPane(); + } + + protected JPanel createMainStylePane4WidgetLayout() { + initMainComponents(); + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] rowSize = {p, p, p, p, p}; + double[] columnSize = {SETTING_LABEL_WIDTH, f}; + + JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ + {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Frame_Style")), null}, + {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Render_Style")), borderStyleCombo}, + {this.borderLineAndImagePane, null}, + {this.createMainBackgroundAndOpacityPane(), null}, + {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Radius")), cornerSpinner}, + }, + rowSize, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); + contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); + + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.setBorder(new BottomLineBorder()); + container.add(contentPane, BorderLayout.NORTH); + + return container; + } + + protected JPanel createMainStylePane4RootLayout() { + initMainComponents(); + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] rowSize = {p, p}; + double[] columnSize = {SETTING_LABEL_WIDTH, f}; + + JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ + {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Frame_Style")), null}, + {this.createMainBackgroundAndOpacityPane(), null}, + }, + rowSize, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); + contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); + + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.setBorder(new BottomLineBorder()); + container.add(contentPane, BorderLayout.NORTH); + + return container; + } + + protected JPanel createMainBackgroundAndOpacityPane() { + return createBackgroundAndOpacityPane( + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Body_Background"), + this.backgroundPane, + this.backgroundOpacityPane); + } + + protected void initTitleComponents() { + titleVisibleCheckbox = new UICheckBox(); + + titleTextPane = new TinyFormulaPane(); + + titleFontFamilyComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report()); + titleFontFamilyComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Family")); + + titleFontSizeComboBox = new UIComboBox(FRFontPane.FONT_SIZES); + titleFontSizeComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Size")); + + titleFontColorSelectPane = new UIColorButton(); + titleFontColorSelectPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Foreground")); + titleFontColorSelectPane.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Foreground")); + + titleFontBoldButton = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/bold.png")); + titleFontBoldButton.setPreferredSize(BUTTON_SIZE); + titleFontBoldButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Bold")); + titleFontBoldButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Bold")); + + titleFontItalicButton = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/italic.png")); + titleFontItalicButton.setPreferredSize(BUTTON_SIZE); + titleFontItalicButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Italic")); + titleFontItalicButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Italic")); + + titleFontUnderlineButton = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/underline.png")); + titleFontUnderlineButton.setPreferredSize(BUTTON_SIZE); + titleFontUnderlineButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Underline")); + titleFontUnderlineButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Underline")); + + titleFontUnderlineCombo = new LineComboBox(UIConstants.BORDER_LINE_STYLE_ARRAY); + titleFontUnderlineCombo.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Line_Style")); + + titleInsetImagePane = new TitleInsetImagePane(); + + titleAlignPane = new UIButtonGroup( + new Icon[] { + IconUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_left_normal.png"), + IconUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_center_normal.png"), + IconUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_right_normal.png") + }, + new Integer[]{Constants.LEFT, Constants.CENTER, Constants.RIGHT}); + titleAlignPane.setAllToolTips( + new String[] { + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Left"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Center"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Right") + }); + + titleBackgroundPane = new LayoutBackgroundSpecialPane(); + + titleBackgroundOpacityPane = new UIPercentDragPane(); + } + + protected JPanel createTitleStylePane() { + initTitleComponents(); + + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] rowSize = {p,p,p,p,p,p}; + double[] columnSize = {SETTING_LABEL_WIDTH, f}; + + final JPanel bottomPane = TableLayoutHelper.createCommonTableLayoutPane( new JComponent[][]{ + {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Content")), titleTextPane}, + {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Format")), titleFontFamilyComboBox}, + {null, createTitleFontButtonPane()}, + {titleInsetImagePane, null}, + {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Text_Align")), titleAlignPane}, + {this.createTitleBackgroundAndOpacityPane(), null}, + }, + rowSize, columnSize, IntervalConstants.INTERVAL_L1); + bottomPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + bottomPane.setVisible(false); + + JPanel visibleComposedPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + titleVisibleCheckbox.setSelected(false); + visibleComposedPane.add(titleVisibleCheckbox, BorderLayout.WEST); + visibleComposedPane.add(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Visible")), BorderLayout.CENTER); + + JPanel topPane = TableLayoutHelper.createCommonTableLayoutPane( new JComponent[][] { + {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title")), null}, + {visibleComposedPane, null} + }, new double[]{p, p}, new double[]{SETTING_LABEL_WIDTH, p}, IntervalConstants.INTERVAL_L1); + topPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); + + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.setBorder(new BottomLineBorder()); + container.add(topPane, BorderLayout.NORTH); + container.add(bottomPane, BorderLayout.CENTER); + + titleVisibleCheckbox.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + bottomPane.setVisible(titleVisibleCheckbox.isSelected()); + } + }); + + return container; + } + + protected JPanel createTitleFontButtonPane(){ + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] rowSize = {p}; + double[] columnSize = {f, p, p, p, p}; + + JPanel buttonPane = TableLayoutHelper.createCommonTableLayoutPane( new JComponent[][] { + {titleFontSizeComboBox, titleFontColorSelectPane, titleFontItalicButton, titleFontBoldButton, titleFontUnderlineButton}, + }, rowSize, columnSize, IntervalConstants.INTERVAL_W0); + + JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + containerPane.add(buttonPane, BorderLayout.NORTH); + containerPane.add(titleFontUnderlineCombo, BorderLayout.CENTER); + + titleFontUnderlineCombo.setVisible(false); + titleFontUnderlineButton.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + titleFontUnderlineCombo.setVisible(titleFontUnderlineButton.isSelected()); + } + }); + + return containerPane; + } + + protected JPanel createTitleBackgroundAndOpacityPane() { + return createBackgroundAndOpacityPane( + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Background"), + titleBackgroundPane, + titleBackgroundOpacityPane); + } + + @Override + public LayoutBorderStyle updateBean() { + LayoutBorderStyle style = new LayoutBorderStyle(); + updateMain(style); + updateTitle(style); + return style; + } + + protected void updateMain(LayoutBorderStyle style) { + if (borderStyleCombo != null) { + style.setBorderStyle(borderStyleCombo.getSelectedIndex()); + } + if (cornerSpinner != null) { + style.setBorderRadius((int) cornerSpinner.getValue()); + } + if (borderLineAndImagePane != null) { + borderLineAndImagePane.updateBean(style); + } + if (backgroundPane != null) { + style.setBackground(backgroundPane.update()); + } + if (backgroundOpacityPane != null) { + style.setAlpha((float)backgroundOpacityPane.updateBean()); + } + } + + protected void updateTitle(LayoutBorderStyle style) { + style.setType(titleVisibleCheckbox != null && titleVisibleCheckbox.isSelected() ? LayoutBorderStyle.TITLE : LayoutBorderStyle.STANDARD); + TitlePacker title = style.getTitle() == null ? new WidgetTitle() : style.getTitle(); + title.setTextObject(titleTextPane.updateBean()); + FRFont frFont = title.getFrFont(); + frFont = frFont.applySize((Integer) titleFontSizeComboBox.getSelectedItem()); + frFont = frFont.applyName(titleFontFamilyComboBox.getSelectedItem().toString()); + frFont = frFont.applyForeground(titleFontColorSelectPane.getColor()); + frFont = updateTitleFontItalicBold(frFont); + int line = titleFontUnderlineButton.isSelected() ? this.titleFontUnderlineCombo.getSelectedLineStyle() : Constants.LINE_NONE; + frFont = frFont.applyUnderline(line); + title.setFrFont(frFont); + title.setPosition((Integer) titleAlignPane.getSelectedItem()); + titleInsetImagePane.updateBean(title); + title.setBackground(titleBackgroundPane.update()); + title.setBackgroundOpacity((float)titleBackgroundOpacityPane.updateBean()); + style.setTitle(title); + } + + private FRFont updateTitleFontItalicBold(FRFont frFont) { + int italic_bold = frFont.getStyle(); + boolean isItalic = italic_bold == Font.ITALIC || italic_bold == (Font.BOLD + Font.ITALIC); + boolean isBold = italic_bold == Font.BOLD || italic_bold == (Font.BOLD + Font.ITALIC); + if (titleFontItalicButton.isSelected() && !isItalic) { + italic_bold += Font.ITALIC; + } else if (!titleFontItalicButton.isSelected() && isItalic) { + italic_bold -= Font.ITALIC; + } + frFont = frFont.applyStyle(italic_bold); + if (titleFontBoldButton.isSelected() && !isBold) { + italic_bold += Font.BOLD; + } else if (!titleFontBoldButton.isSelected() && isBold) { + italic_bold -= Font.BOLD; + } + frFont = frFont.applyStyle(italic_bold); + return frFont; + } + + @Override + public void populateBean(LayoutBorderStyle style) { + if(this.style == null) { + this.style = new LayoutBorderStyle(); + } + this.style.setStyle(style); + + populateMain(); + populateTitle(); + } + + protected void populateMain() { + if (this.borderStyleCombo != null) { + this.borderStyleCombo.setSelectedIndex(style.getBorderStyle()); + } + if (this.borderLineAndImagePane != null) { + this.borderLineAndImagePane.populateBean(style); + } + if (this.backgroundPane != null) { + this.backgroundPane.populateBean(style.getBackground()); + if (this.backgroundOpacityPane != null) { + this.backgroundOpacityPane.populateBean(style.getAlpha()); + } + } + if (this.cornerSpinner != null) { + this.cornerSpinner.setValue(style.getBorderRadius()); + } + } + + protected void populateTitle() { + TitlePacker widgetTitle = style == null ? new WidgetTitle() : style.getTitle(); + widgetTitle = widgetTitle == null ? new WidgetTitle() : widgetTitle; + titleVisibleCheckbox.setSelected(style.getType() != LayoutBorderStyle.STANDARD); + + this.titleTextPane.populateBean(widgetTitle.getTextObject().toString()); + + FRFont frFont = widgetTitle.getFrFont(); + this.titleFontSizeComboBox.setSelectedItem(frFont.getSize()); + this.titleFontFamilyComboBox.setSelectedItem(frFont.getFamily()); + this.titleFontColorSelectPane.setColor(frFont.getForeground()); + this.titleFontColorSelectPane.repaint(); + titleFontBoldButton.setSelected(frFont.isBold()); + titleFontItalicButton.setSelected(frFont.isItalic()); + + int line = frFont.getUnderline(); + if (line == Constants.LINE_NONE) { + titleFontUnderlineButton.setSelected(false); + titleFontUnderlineCombo.setVisible(false); + } else { + titleFontUnderlineButton.setSelected(true); + titleFontUnderlineCombo.setVisible(true); + this.titleFontUnderlineCombo.setSelectedLineStyle(line); + } + + titleAlignPane.setSelectedItem(widgetTitle.getPosition()); + titleInsetImagePane.populateBean(widgetTitle); + titleBackgroundPane.populateBean(widgetTitle.getBackground()); + titleBackgroundOpacityPane.populateBean(widgetTitle.getBackgroundOpacity()); + } + + @Override + protected String title4PopupWindow() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style"); + } + + private static JPanel createBackgroundAndOpacityPane(String name, BackgroundSpecialPane backgroundPane, UIPercentDragPane opacityPane) { + JPanel container = new JPanel(); + container.setLayout(new BorderLayout(0, 6)); + + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] columnSize = {SETTING_LABEL_WIDTH, f}; + + // 确保BackgroundSpecialPane高度变化时,Label依然保持与其顶部对齐 + JPanel backgroundLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + backgroundLabelPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0)); + backgroundLabelPane.add(new UILabel(name), BorderLayout.NORTH); + + JPanel backgroundComposedPane = TableLayoutHelper.createGapTableLayoutPane( + new JComponent[][]{ + {backgroundLabelPane, backgroundPane} + }, + new double[]{p}, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); + + JPanel opacityComposedPane = TableLayoutHelper.createGapTableLayoutPane( + new JComponent[][]{ + {new UILabel(""), new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Alpha"))}, + {new UILabel(""), opacityPane} + }, + new double[]{p, p}, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); + + container.add(backgroundComposedPane, BorderLayout.NORTH, 0); + container.add(opacityComposedPane, BorderLayout.CENTER, 1); + + opacityComposedPane.setVisible(false); + + backgroundPane.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + Background background = backgroundPane.update(); + opacityComposedPane.setVisible(background != null); + } + }); + + return container; + } + + protected static class BottomLineBorder extends LineBorder { + + public BottomLineBorder() { + super(Color.lightGray, 1); + } + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + Graphics2D g2d = (Graphics2D) g; + Color oldColor = g2d.getColor(); + g2d.setColor(this.lineColor); + GraphHelper.drawLine(g, 0, height, width, height, 1); + g2d.setColor(oldColor); + } + } + + protected static class LayoutBackgroundSpecialPane extends BackgroundSpecialPane { + @Override + protected GradientBackgroundQuickPane createGradientBackgroundQuickPane() { + return new GradientBackgroundQuickPane(140); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/TitleInsetImagePane.java b/designer-form/src/main/java/com/fr/design/gui/xpane/TitleInsetImagePane.java new file mode 100644 index 000000000..b7161cbfb --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/gui/xpane/TitleInsetImagePane.java @@ -0,0 +1,311 @@ +package com.fr.design.gui.xpane; + +import com.fr.base.Style; +import com.fr.base.background.ImageBackground; +import com.fr.base.background.ImageFileBackground; +import com.fr.design.border.UIRoundedBorder; +import com.fr.design.constants.UIConstants; +import com.fr.design.designer.IntervalConstants; +import com.fr.design.event.UIObserver; +import com.fr.design.event.UIObserverListener; +import com.fr.design.gui.frpane.ImgChooseWrapper; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIButtonGroup; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.ispinner.UISpinner; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.backgroundpane.ImagePreviewPane; +import com.fr.design.style.background.image.ImageFileChooser; +import com.fr.design.widget.ui.designer.component.UIBoundSpinner; +import com.fr.form.ui.WidgetTitle; +import com.fr.general.Background; +import com.fr.general.IOUtils; +import com.fr.general.ImageWithSuffix; +import com.fr.general.act.TitlePacker; +import com.fr.stable.Constants; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.basic.BasicButtonUI; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.geom.RoundRectangle2D; + +/** + * @author Starryi + * @version 10.0.18 + * Created by Starryi on 2021/7/3 + */ +public class TitleInsetImagePane extends JPanel implements UIObserver { + private final int SETTING_LABEL_WIDTH = LayoutStylePane.SETTING_LABEL_WIDTH; + private final int DELETE_BUTTON_SIZE = 24; + private final int IMAGE_PREVIEW_SIZE = 145; + private final Style DEFAULT_IMAGE_LAYOUT_STYLE = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_DEFAULT); + private final int DEFAULT_INSET_LOCATION_INDEX = 0; + private final int DEFAULT_INSET_PADDING = 10; + + private UIObserverListener uiObserverListener; + + private UIButton imageChooseButton; + private UIButton imageDeleteButton; + private ImagePreviewPane imagePreviewPane; + private UIButtonGroup imageLocationPane; + private UISpinner imagePaddingPane; + + private ImageFileChooser imageFileChooser; + + public TitleInsetImagePane() { + this.initComponents(); + this.initLayout(); + } + + private JPanel createImageChooseComposedPane() { + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] rowSize = {p}; + double[] columnSize = {SETTING_LABEL_WIDTH, f}; + + return TableLayoutHelper.createCommonTableLayoutPane( new JComponent[][]{ + {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Inset")), this.imageChooseButton}, + }, + rowSize, columnSize, IntervalConstants.INTERVAL_L1); + } + + private JPanel createImageContentComposedPane() { + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] rowSize = {p, p, p, p, p}; + double[] columnSize = {SETTING_LABEL_WIDTH, f}; + + JPanel deletableImagePreviewPane = new JPanel(); + deletableImagePreviewPane.setLayout(null); + deletableImagePreviewPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, 5)); + deletableImagePreviewPane.setPreferredSize(new Dimension(IMAGE_PREVIEW_SIZE, IMAGE_PREVIEW_SIZE)); + imagePreviewPane.setBounds(0, 0, IMAGE_PREVIEW_SIZE, IMAGE_PREVIEW_SIZE); + imageDeleteButton.setBounds(IMAGE_PREVIEW_SIZE - DELETE_BUTTON_SIZE, 0, DELETE_BUTTON_SIZE, DELETE_BUTTON_SIZE); + deletableImagePreviewPane.add(imageDeleteButton, 0); + deletableImagePreviewPane.add(imagePreviewPane, 1); + + imageDeleteButton.setVisible(false); + imageDeleteButton.setEnabled(false); + deletableImagePreviewPane.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + super.mouseEntered(e); + imageDeleteButton.setVisible(true); + imageDeleteButton.setEnabled(true); + } + + @Override + public void mouseExited(MouseEvent e) { + super.mouseExited(e); + int x = e.getX(); + int y = e.getY(); + if (x <= 0 || getWidth() <= x || y <= 0 || y >= getHeight()) { + imageDeleteButton.setVisible(false); + imageDeleteButton.setEnabled(false); + } + } + }); + + return TableLayoutHelper.createCommonTableLayoutPane( + new JComponent[][]{ + {null, deletableImagePreviewPane}, + {null, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Inset_Relative_Location"))}, + {null, this.imageLocationPane}, + {null, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Inset_Padding"))}, + {null, this.imagePaddingPane} + }, + rowSize, columnSize, IntervalConstants.INTERVAL_L1); + } + + private void initImageFileChooserIfNotExist() { + if (imageFileChooser == null) { + imageFileChooser = new ImageFileChooser(); + imageFileChooser.setMultiSelectionEnabled(false); + } + } + + private void initComponents() { + imageChooseButton = new UIButton(IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_choose_inset.png")); + + imageDeleteButton = new OpaqueColorButton( + IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_delete_inset.png"), + new Color(51, 51, 52, 178), + 2); + imageDeleteButton.setPreferredSize(new Dimension(DELETE_BUTTON_SIZE, DELETE_BUTTON_SIZE)); + + imagePreviewPane = new ImagePreviewPane(); + imagePreviewPane.setImageStyle(DEFAULT_IMAGE_LAYOUT_STYLE); + imagePreviewPane.setPreferredSize(new Dimension(IMAGE_PREVIEW_SIZE, IMAGE_PREVIEW_SIZE)); + + imageLocationPane = new UIButtonGroup(new Icon[][]{ + { + IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_inset_left_selected.png"), + IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_inset_left_unselected.png") + }, + { + IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_inset_both_selected.png"), + IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_inset_both_unselected.png") + }, + { + IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_inset_right_selected.png"), + IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_inset_right_unselected.png") + }, + }); + imageLocationPane.setSelectedIndex(DEFAULT_INSET_LOCATION_INDEX); + imageLocationPane.setAllToolTips(new String[]{ + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Inset_Relative_Left_Tooltip"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Inset_Relative_Both_Tooltip"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Inset_Relative_Right_Tooltip"), + }); + + imagePaddingPane = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, WidgetTitle.DEFAULT_INSET_PADDING); + imagePaddingPane.setValue(DEFAULT_INSET_PADDING); + } + + private void initLayout() { + + + this.setLayout(new BorderLayout(0, IntervalConstants.INTERVAL_L1)); + + add(createImageChooseComposedPane(), BorderLayout.NORTH, 0); + add(createImageContentComposedPane(), BorderLayout.CENTER, 1); + + getComponent(1).setVisible(false); + + this.imageChooseButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + initImageFileChooserIfNotExist(); + + int returnVal = imageFileChooser.showOpenDialog(DesignerContext.getDesignerFrame()); + ImgChooseWrapper.getInstance(imagePreviewPane, imageFileChooser, DEFAULT_IMAGE_LAYOUT_STYLE, new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + if (!getComponent(1).isVisible()) { + imageLocationPane.setSelectedIndex(DEFAULT_INSET_LOCATION_INDEX); + imagePaddingPane.setValue(DEFAULT_INSET_PADDING); + getComponent(1).setVisible(true); + } + + fireStateChanged(); + } + }).dealWithImageFile(returnVal); + } + }); + this.imageDeleteButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + imagePreviewPane.setImageWithSuffix(null); + imageLocationPane.setSelectedIndex(DEFAULT_INSET_LOCATION_INDEX); + imagePaddingPane.setValue(DEFAULT_INSET_PADDING); + getComponent(1).setVisible(false); + + fireStateChanged(); + } + }); + } + + public void populateBean(TitlePacker packer) { + Background insetImage = packer.getInsetImage(); + if (insetImage instanceof ImageBackground) { + ImageWithSuffix image = ((ImageBackground) insetImage).getImageWithSuffix(); + if (image != null) { + this.imagePreviewPane.setImageWithSuffix(image); + + if (!packer.isInsetRelativeTextLeft()) { + this.imageLocationPane.setSelectedIndex(2); + } else if (!packer.isInsetRelativeTextRight()) { + this.imageLocationPane.setSelectedIndex(0); + } else { + this.imageLocationPane.setSelectedIndex(1); + } + + this.imagePaddingPane.setValue(packer.getInsetImagePadding()); + + getComponent(1).setVisible(true); + + return; + } + } + + this.imagePreviewPane.setImageWithSuffix(null); + this.imageLocationPane.setSelectedIndex(DEFAULT_INSET_LOCATION_INDEX); + this.imagePaddingPane.setValue(DEFAULT_INSET_PADDING); + + getComponent(1).setVisible(false); + } + + public void updateBean(TitlePacker packer) { + Image image = imagePreviewPane.getImageWithSuffix(); + if (image != null) { + packer.setInsetImage(new ImageFileBackground(image, Constants.IMAGE_DEFAULT)); + + int imageLocationIndex = this.imageLocationPane.getSelectedIndex(); + packer.setInsetRelativeTextLeft(imageLocationIndex == 0 || imageLocationIndex == 1); + packer.setInsetRelativeTextRight(imageLocationIndex == 2 || imageLocationIndex == 1); + + packer.setInsetImagePadding((int) this.imagePaddingPane.getValue()); + } else { + packer.setInsetImage(null); + packer.setInsetImagePadding(WidgetTitle.DEFAULT_INSET_PADDING); + packer.setInsetRelativeTextLeft(WidgetTitle.DEFAULT_INSET_LEFT); + packer.setInsetRelativeTextRight(WidgetTitle.DEFAULT_INSET_RIGHT); + } + } + + private void fireStateChanged() { + if (uiObserverListener != null) { + uiObserverListener.doChange(); + } + } + + @Override + public void registerChangeListener(UIObserverListener listener) { + this.uiObserverListener = listener; + } + + @Override + public boolean shouldResponseChangeListener() { + return true; + } + + private static class OpaqueColorButton extends UIButton { + private final Color color; + private final int radius; + + public OpaqueColorButton(Icon icon, Color color, int radius) { + super(icon); + setUI(new BasicButtonUI()); + setOpaque(true); + setBorderPainted(false); + setBorder(null); + setFocusPainted(false); + setContentAreaFilled(false); + this.color = color; + this.radius = radius; + } + + @Override + public void paint(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + Color oldColor = g2d.getColor(); + + Shape shape = new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), radius, radius); + g2d.clip(shape); + g2d.setColor(color); + g2d.fillRect(0, 0, getWidth(), getHeight()); + + g2d.setColor(oldColor); + super.paint(g); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java b/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java index c9ae03272..134252487 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java @@ -2,15 +2,20 @@ package com.fr.design.mainframe; import com.fr.design.constants.UIConstants; import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.treeview.ComponentTreeCellRenderer; import com.fr.design.designer.treeview.ComponentTreeModel; import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.gui.itree.UITreeUI; +import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.GUICoreUtils; -import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; import com.fr.stable.StringUtils; +import java.awt.Rectangle; +import java.awt.event.MouseListener; +import java.util.Stack; import javax.swing.BorderFactory; import javax.swing.DropMode; import javax.swing.JPanel; @@ -370,6 +375,81 @@ public class ComponentTree extends JTree { public void mouseExited(MouseEvent e) { hidePreviewPane(); } + + @Override + public void mouseClicked(MouseEvent e) { + // 鼠标左键 双击 + if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1 && !designer.isFormParaDesigner()) { + Point p = e.getPoint(); + // 解析组件树路径 获取选中的组件 + int selRow = tree.getRowForLocation(p.x, p.y); + TreePath path = tree.getPathForRow(selRow); + Rectangle bounds = tree.getPathBounds(path); + if (bounds != null) { + Point point = bounds.getLocation(); + SwingUtilities.convertPointToScreen(point, tree); + XCreator comp = (XCreator) path.getLastPathComponent(); + startEditing(comp, e); + } + } + } + + /** + * 组件进入编辑状态 + * + * @param comp + * @param e + */ + private void startEditing(XCreator comp, MouseEvent e) { + designer.getSelectionModel().selectACreator(comp); + Rectangle rectangle = getRelativeBounds(comp); + int x = rectangle.x + rectangle.width / 2; + int y = rectangle.y + rectangle.height / 2; + XCreator creator = comp.getEditingChildCreator(); + MouseListener[] listeners = designer.getMouseListeners(); + if (ArrayUtils.isNotEmpty(listeners) && listeners[0] instanceof EditingMouseListener) { + responseClickAll(creator, (EditingMouseListener) listeners[0], new MouseEvent(creator, MouseEvent.MOUSE_CLICKED, e.getWhen(), e.getModifiers(), x, y, e.getClickCount(), false)); + } + } + + /** + * 自父容器到子组件 每一层的都响应click事件 + * + * + * @param creator + * @param editingMouseListener + * @param mouseEvent + */ + public void responseClickAll(XCreator creator, EditingMouseListener editingMouseListener, MouseEvent mouseEvent) { + Stack stack = new Stack<>(); + stack.push(creator); + while (creator.getParent() instanceof XCreator) { + creator = (XCreator) creator.getParent(); + stack.push(creator); + } + while (!stack.isEmpty()) { + stack.pop().respondClick(editingMouseListener, mouseEvent); + } + } + + + /** + * 获取组件范围坐标 + * + * @param creator + * @return + */ + private Rectangle getRelativeBounds(XCreator creator) { + Rectangle bounds = creator.getBounds(); + XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(creator); + if (parent == null) { + return bounds; + } + Rectangle rec = ComponentUtils.getRelativeBounds(parent); + bounds.x += rec.x; + bounds.y += rec.y; + return bounds; + } } private class PopupPreviewPane extends JPopupMenu { diff --git a/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java b/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java index fd1236091..00ba360bb 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java @@ -21,6 +21,7 @@ import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWFitLayout; import com.fr.design.designer.creator.cardlayout.XCardSwitchButton; import com.fr.design.designer.creator.cardlayout.XWCardLayout; +import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; import com.fr.design.form.util.XCreatorConstants; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.imenu.UIPopupMenu; @@ -29,6 +30,7 @@ import com.fr.design.icon.IconPathConstants; import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.LayoutUtils; +import com.fr.general.ComparatorUtils; import com.fr.stable.Constants; import javax.swing.BorderFactory; @@ -353,6 +355,15 @@ public class EditingMouseListener extends MouseInputAdapter { } + private void processCoverPane(XCreator component) { + // selected状态 不展示封面 + XCreator xCreator = selectionModel.getSelection().getSelectedCreator(); + boolean accept = xCreator == null || !ComparatorUtils.equals(xCreator.toData().getWidgetName(), component.toData().getWidgetName()) ||!xCreator.isSelected(); + if (accept) { + component.displayCoverPane(true); + } + } + private boolean isShareConfigButton(MouseEvent e, XCreator component, Insets insets) { if (component.isShared()) { int minX = getParentPositionX(component, component.getX()) + component.getWidth() - insets.right - CoverReportPane.SHARE_CONF_BTN_W - designer.getHorizontalScaleValue(); @@ -387,7 +398,7 @@ public class EditingMouseListener extends MouseInputAdapter { private void elementCaseMouseMoved(MouseEvent e, XCreator component) { xElementCase = (XElementCase) component; - component.displayCoverPane(true); + processCoverPane(component); processCoverMouseMove(component, e); } @@ -428,14 +439,14 @@ public class EditingMouseListener extends MouseInputAdapter { private void processChartEditorMouseMove(XCreator component, MouseEvent e) { if (component instanceof XChartEditor) { xChartEditor = (XChartEditor) component; - component.displayCoverPane(true); + processCoverPane(component); processCoverMouseMove(component, e); } } private void processCoverMouseMove(XCreator component, MouseEvent e) { - component.setShareConfigButtonFocus(false); + component.setHelpBtnOnFocus(false); Insets insets; if (component instanceof XBorderStyleWidgetCreator) { insets = ((XBorderStyleWidgetCreator) component).getInsets(); @@ -447,7 +458,7 @@ public class EditingMouseListener extends MouseInputAdapter { } if (isShareConfigButton(e, component, insets)) { designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - component.setShareConfigButtonFocus(true); + component.setHelpBtnOnFocus(true); } else if (isEditButton(e, component, insets)) { designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } @@ -475,7 +486,12 @@ public class EditingMouseListener extends MouseInputAdapter { if (DesignerMode.isAuthorityEditing()) { return; } - if ((e.isShiftDown() || InputEventBaseOnOS.isControlDown(e)) && !stateModel.isSelecting()) { + boolean shiftSelecting = e.isShiftDown(); + boolean ctrlSelecting = InputEventBaseOnOS.isControlDown(e); + int currentCursorType = this.designer.getCursor().getType(); + boolean shiftResizing = e.isShiftDown() && ( Cursor.SW_RESIZE_CURSOR <= currentCursorType && currentCursorType <= Cursor.E_RESIZE_CURSOR); + + if ((shiftSelecting || ctrlSelecting) && !shiftResizing && !stateModel.isSelecting()) { stateModel.startSelecting(e); } // 如果当前是左键拖拽状态,拖拽组件 @@ -603,10 +619,23 @@ public class EditingMouseListener extends MouseInputAdapter { return; } + XCreator oldCreator = creator; creator = processTopLayoutMouseClick(creator); if (creator != null) { - creator.respondClick(this, e); + if (e.getClickCount() == 1 && designer.getCursor().getType() != Cursor.HAND_CURSOR) { + setCoverPaneNotDisplay(creator, e, false); + selectionModel.selectACreatorAtMouseEvent(e); + refreshTopXCreator(); + XCreator[] xCreators = selectionModel.getSelection().getSelectedCreators(); + for (XCreator xCreator : xCreators) { + xCreator.setSelected(true); + } + } else if (responseTabLayout(oldCreator, e)) { + // do nothing + } else { + creator.respondClick(this, e); + } if (e.getButton() == MouseEvent.BUTTON3) { UIPopupMenu cellPopupMenu = creator.createPopupMenu(designer); if (cellPopupMenu != UIPopupMenu.EMPTY) { @@ -619,6 +648,16 @@ public class EditingMouseListener extends MouseInputAdapter { LayoutUtils.layoutRootContainer(designer.getRootComponent()); } + private boolean responseTabLayout(XCreator creator, MouseEvent e) { + if (creator.acceptType(XWCardMainBorderLayout.class) ) { + creator.respondClick(this, e); + return true; + } else if (creator.getParent() instanceof XCreator) { + return responseTabLayout((XCreator) creator.getParent(), e); + } + return false; + } + /** * 离开 diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java index 01a46d25b..30b941818 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java @@ -49,6 +49,7 @@ import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; +import javax.swing.SwingUtilities; /** * 添加模式下鼠标事件处理器。 @@ -66,6 +67,8 @@ public class FormCreatorDropTarget extends DropTarget { private AddingModel addingModel; private static final int GAP = 30; + private TabDragInner tabDragInner; + private JWindow promptWindow = new JWindow(); private UIButton promptButton = new UIButton("", BaseUtils.readIcon(IconPathConstants.FORBID_ICON_PATH)); @@ -73,6 +76,7 @@ public class FormCreatorDropTarget extends DropTarget { this.designer = designer; this.addingModel = designer.getAddingModel(); this.promptWindow.add(promptButton); + this.tabDragInner = new TabDragInner(designer); } private void adding(int x, int y) { @@ -128,6 +132,7 @@ public class FormCreatorDropTarget extends DropTarget { designer.getSelectionModel().setSelectedCreators( FormSelectionUtils.rebuildSelection(xCreator, new Widget[]{widget})); designer.getEditListenerTable().fireCreatorModified(addingModel.getXCreator(), DesignerEvent.CREATOR_ADDED); + tabDragInner.tryDragIn(); } else { Toolkit.getDefaultToolkit().beep(); } @@ -263,7 +268,10 @@ public class FormCreatorDropTarget extends DropTarget { @Override public synchronized void dragOver(DropTargetDragEvent dtde) { Point loc = dtde.getLocation(); - hovering(designer.getRelativeX(loc.x), designer.getRelativeY(loc.y)); + int x = designer.getRelativeX(loc.x); + int y = designer.getRelativeY(loc.y); + hovering(x, y); + tabDragInner.canDragIn(designer.getComponentAt(x, y), x, y); } /** @@ -295,6 +303,16 @@ public class FormCreatorDropTarget extends DropTarget { public synchronized void drop(DropTargetDropEvent dtde) { Point loc = dtde.getLocation(); this.adding(designer.getRelativeX(loc.x), designer.getRelativeY(loc.y)); + // 放到事件末尾执行 + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + // 拖拽释放后标记未选中 + for (XCreator xCreator : designer.getSelectionModel().getSelection().getSelectedCreators()) { + xCreator.setSelected(true); + } + } + }); //针对在表单中拖入一个控件直接ctrl+s无反应 designer.requestFocus(); } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java b/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java index 7cd9e2108..c49902c8d 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java @@ -13,6 +13,7 @@ import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWFitLayout; +import com.fr.design.designer.creator.XWTitleLayout; import com.fr.design.form.util.XCreatorConstants; import com.fr.design.roleAuthority.ReportAndFSManagePane; import com.fr.design.utils.ComponentUtils; @@ -307,7 +308,10 @@ public class FormDesignerUI extends ComponentUI { bounds.x -= designer.getHorizontalScaleValue(); bounds.y -= designer.getVerticalScaleValue(); - drawResizingThumbs(g, selectionModel.getSelection().getDirections(), bounds.x, bounds.y, bounds.width, bounds.height); + // 绘制调整框线 + if (designer.getStateModel().getDirection() != null) { + drawResizingThumbs(g, selectionModel.getSelection().getDirections(), bounds.x, bounds.y, bounds.width, bounds.height, designer.getStateModel().getDirection().getActual()); + } //选中时边框颜色 g.setColor(XCreatorConstants.FORM_BORDER_COLOR); @@ -321,6 +325,8 @@ public class FormDesignerUI extends ComponentUI { resetCreatorBounds(creatorBounds); } creator.paintBorder(g, creatorBounds); + // 拖拽时不绘制 + creator.showSelectedPopup(designer, creatorBounds, !designer.getStateModel().isDragging() && creator.acceptType(XWTitleLayout.class)); } } @@ -357,48 +363,60 @@ public class FormDesignerUI extends ComponentUI { /** * 画出八个拖拽框 */ - private void drawResizingThumbs(Graphics g, int[] directions, int x, int y, int w, int h) { + private void drawResizingThumbs(Graphics g, int[] directions, int x, int y, int w, int h, int direction) { int bx = x - XCreatorConstants.RESIZE_BOX_SIZ; int by = y - XCreatorConstants.RESIZE_BOX_SIZ; - if (ArrayUtils.contains(directions, Direction.LEFT_TOP)) { + if (showBox(Direction.LEFT_TOP, direction, directions)) { drawBox(g, bx, by); } - if (ArrayUtils.contains(directions, Direction.TOP)) { + if (showBox(Direction.TOP, direction, directions)) { bx = x + ((w - XCreatorConstants.RESIZE_BOX_SIZ) / 2); drawBox(g, bx, by); } - if (ArrayUtils.contains(directions, Direction.RIGHT_TOP)) { + if (showBox(Direction.RIGHT_TOP, direction, directions)) { bx = x + w; drawBox(g, bx, by); } - if (ArrayUtils.contains(directions, Direction.LEFT)) { + if (showBox(Direction.LEFT, direction, directions)) { bx = x - XCreatorConstants.RESIZE_BOX_SIZ; by = y + ((h - XCreatorConstants.RESIZE_BOX_SIZ) / 2); drawBox(g, bx, by); } - if (ArrayUtils.contains(directions, Direction.LEFT_BOTTOM)) { + if (showBox(Direction.LEFT_BOTTOM, direction, directions)) { bx = x - XCreatorConstants.RESIZE_BOX_SIZ; by = y + h; drawBox(g, bx, by); } - if (ArrayUtils.contains(directions, Direction.BOTTOM)) { + if (showBox(Direction.BOTTOM, direction, directions)) { bx = x + ((w - XCreatorConstants.RESIZE_BOX_SIZ) / 2); by = y + h; drawBox(g, bx, by); } - if (ArrayUtils.contains(directions, Direction.RIGHT_BOTTOM)) { + if (showBox(Direction.RIGHT_BOTTOM, direction, directions)) { bx = x + w; by = y + h; drawBox(g, bx, by); } - if (ArrayUtils.contains(directions, Direction.RIGHT)) { + if (showBox(Direction.RIGHT, direction, directions)) { bx = x + w; by = y + ((h - XCreatorConstants.RESIZE_BOX_SIZ) / 2); drawBox(g, bx, by); } } + /** + * 是否展示某个方位的调整框 + * + * @param currentDirection + * @param actualDirection + * @param directions + * @return + */ + private boolean showBox(int currentDirection, int actualDirection, int[] directions) { + return ArrayUtils.contains(directions, currentDirection) && (currentDirection == actualDirection || !designer.getStateModel().isDragging()); + } + /** * 画每一个小拖拽框 */ diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormEditorKeyListener.java b/designer-form/src/main/java/com/fr/design/mainframe/FormEditorKeyListener.java index 81f3d6efc..13209710f 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormEditorKeyListener.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormEditorKeyListener.java @@ -27,7 +27,11 @@ public class FormEditorKeyListener extends KeyAdapter{ @Override public void keyPressed(KeyEvent e) { - if(e.isShiftDown() || InputEventBaseOnOS.isControlDown(e)) { + boolean shiftSelecting = e.isShiftDown(); + boolean ctrlSelecting = InputEventBaseOnOS.isControlDown(e); + int currentCursorType = this.designer.getCursor().getType(); + boolean shiftResizing = e.isShiftDown() && ( Cursor.SW_RESIZE_CURSOR <= currentCursorType && currentCursorType <= Cursor.E_RESIZE_CURSOR); + if((shiftSelecting || ctrlSelecting) && !shiftResizing) { designer.setCursor(ADDCURSOR); } int code = e.getKeyCode(); @@ -57,7 +61,11 @@ public class FormEditorKeyListener extends KeyAdapter{ } public void keyReleased(KeyEvent e) { - if(!(e.isShiftDown() || InputEventBaseOnOS.isControlDown(e))) { + boolean shiftSelecting = e.isShiftDown(); + boolean ctrlSelecting = InputEventBaseOnOS.isControlDown(e); + int currentCursorType = this.designer.getCursor().getType(); + boolean shiftResizing = e.getKeyCode() == KeyEvent.VK_SHIFT && ( Cursor.SW_RESIZE_CURSOR <= currentCursorType && currentCursorType <= Cursor.E_RESIZE_CURSOR); + if(!(shiftSelecting || ctrlSelecting) && !shiftResizing) { designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } if (moved) { diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java b/designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java index d8b604e19..b8f3ff638 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java @@ -7,7 +7,6 @@ import com.fr.design.constants.UIConstants; import com.fr.design.designer.beans.events.DesignerEditListener; import com.fr.design.designer.beans.events.DesignerEvent; import com.fr.design.designer.creator.XCreatorUtils; -import com.fr.design.file.Releasable; import com.fr.design.fun.FormWidgetOptionProvider; import com.fr.design.gui.core.FormWidgetOption; import com.fr.design.gui.core.UserDefinedWidgetOption; @@ -57,7 +56,7 @@ import java.awt.event.MouseEvent; /** * @author null */ -public class FormParaWidgetPane extends JPanel implements Releasable { +public class FormParaWidgetPane extends JPanel { private static FormParaWidgetPane THIS; private final static int BORDER = 5; private final static int WIDGET_WIDTHGAP = 4; @@ -120,15 +119,6 @@ public class FormParaWidgetPane extends JPanel implements Releasable { return THIS; } - public static FormParaWidgetPane getInstance(){ - return THIS; - } - - @Override - public void releaseResources() { - designer = null; - } - public FormParaWidgetPane() { setLayout(new FlowLayout(FlowLayout.LEFT)); DesignerContext.getDesignerFrame().getCenterTemplateCardPane().addComponentListener(new ComponentAdapter() { diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java b/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java index d1d0a2f83..5f48ce294 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java @@ -2,6 +2,7 @@ package com.fr.design.mainframe; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.LayoutAdapter; +import com.fr.design.designer.beans.adapters.layout.FRAbsoluteLayoutAdapter; import com.fr.design.designer.beans.location.Direction; import com.fr.design.designer.creator.XComponent; import com.fr.design.designer.creator.XCreator; @@ -39,6 +40,9 @@ public class FormSelection { * 重置选中的组件 */ public void reset() { + for (XCreator xCreator : selection) { + xCreator.setSelected(false); + } selection.clear(); } @@ -287,6 +291,28 @@ public class FormSelection { } } + public boolean isCreatorAspectRatioLockedInAbsLayout(FormDesigner designer) { + for (XCreator creator : selection) { + LayoutAdapter layoutAdapter = AdapterBus.searchLayoutAdapter(designer, creator); + if (layoutAdapter instanceof FRAbsoluteLayoutAdapter) { + if (creator.toData().isAspectRatioLocked()) { + return true; + } + } + } + return false; + } + + public boolean isCreatorInAbsLayout(FormDesigner designer) { + for (XCreator creator : selection) { + LayoutAdapter layoutAdapter = AdapterBus.searchLayoutAdapter(designer, creator); + if (layoutAdapter instanceof FRAbsoluteLayoutAdapter) { + return true; + } + } + return false; + } + /** * @Description 重置报表块缩略图 * @param: creator diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java index 60a63a0cc..d792f0eca 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java @@ -2,7 +2,6 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; import com.fr.design.dialog.BasicPane; -import com.fr.design.file.Releasable; import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; @@ -31,7 +30,7 @@ import java.util.List; * Date: 14-7-8 * Time: 下午8:18 */ -public class FormWidgetDetailPane extends FormDockView implements Releasable { +public class FormWidgetDetailPane extends FormDockView{ private static final int ONLINE_TAB = 1; private JPanel centerPane; @@ -62,11 +61,6 @@ public class FormWidgetDetailPane extends FormDockView implements Releasable { private static FormWidgetDetailPane singleton = new FormWidgetDetailPane(); } - @Override - public void releaseResources() { - setEditingFormDesigner(null); - } - public String getViewTitle() { return Toolkit.i18nText("Fine-Design_Form_Widget_Tree_And_Table"); } 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 eee57c99f..08969c91a 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 @@ -3,6 +3,7 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; import com.fr.base.PaperSize; import com.fr.base.Parameter; +import com.fr.base.Releasable; import com.fr.base.extension.FileExtension; import com.fr.base.iofile.attr.ExtendSharableAttrMark; import com.fr.base.vcs.DesignerMode; @@ -26,6 +27,7 @@ import com.fr.design.designer.beans.events.DesignerEvent; import com.fr.design.designer.creator.XComponent; import com.fr.design.designer.creator.XCreator; 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.XWAbsoluteBodyLayout; import com.fr.design.designer.creator.XWParameterLayout; @@ -72,6 +74,7 @@ import com.fr.form.share.SharableWidgetProvider; import com.fr.form.share.editor.SharableEditorProvider; import com.fr.form.share.utils.ShareUtils; import com.fr.form.ui.AbstractBorderStyleWidget; +import com.fr.form.ui.ElementCaseEditor; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WBorderLayout; import com.fr.form.ui.container.WLayout; @@ -110,14 +113,13 @@ import java.util.Iterator; import java.util.List; import javax.swing.tree.TreePath; -public class JForm extends JTemplate implements BaseJForm
{ +public class JForm extends JTemplate implements BaseJForm, Releasable { private static final String FORM_CARD = "FORM"; private static final String ELEMENTCASE_CARD = "ELEMENTCASE"; private static final String[] CARDNAME = new String[]{FORM_CARD, ELEMENTCASE_CARD}; private static final int TOOLBARPANEDIMHEIGHT_FORM = 60; - //当前使用的表单设计器 - private static FormDesigner currentFormDesign; + //表单设计器 private FormDesigner formDesign; //格子设计器 @@ -712,7 +714,7 @@ public class JForm extends JTemplate implements BaseJForm implements BaseJForm implements BaseJForm implements BaseJForm TIME_GAP) { + dragInAble = true; + } + } else { + timer = 0; + belowXLayoutContainer = null; + } + if (topLayout != null) { + topLayout.setDragInAble(dragInAble); + } + oldX = x; + oldY = y; + } + + /** + * 尝试进入tab编辑 + */ + public void tryDragIn() { + if (belowXLayoutContainer != null && belowXLayoutContainer.isDragInAble()) { + EditingMouseListener editingMouseListener = new EditingMouseListener(designer); + editingMouseListener.refreshTopXCreator(); + belowXLayoutContainer.setEditable(true); + if (editingMouseListener.stopEditing() && belowXLayoutContainer != designer.getRootComponent()) { + ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, belowXLayoutContainer); + if (adapter != null) { + editingMouseListener.startEditing(belowXLayoutContainer, adapter.getDesignerEditor(), adapter); + } + } + } + } + + + public XLayoutContainer getBelowXLayoutContainer() { + return belowXLayoutContainer; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java b/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java index 9be0d84b2..fd64d3aab 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java @@ -9,7 +9,6 @@ import com.fr.design.designer.creator.*; import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; import com.fr.design.designer.properties.mobile.MobileBookMarkPropertyUI; import com.fr.design.designer.properties.mobile.MobileStylePropertyUI; -import com.fr.design.file.Releasable; import com.fr.design.form.util.FormDesignerUtils; import com.fr.design.fun.WidgetPropertyUIProvider; import com.fr.design.gui.controlpane.EventPropertyPane; @@ -33,7 +32,7 @@ import java.util.Set; * 控件属性表绘制 * Modified by fanglei */ -public class WidgetPropertyPane extends FormDockView implements BaseWidgetPropertyPane, Releasable { +public class WidgetPropertyPane extends FormDockView implements BaseWidgetPropertyPane { private static final int PADDING = 10; private static final int PADDING_M = 12; @@ -69,31 +68,6 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper setLayout(FRGUIPaneFactory.createBorderLayout()); } - @Override - public void releaseResources() { - setEditingFormDesigner(null); - if (eventTable != null) { - eventTable.releaseResources(); - } - if (formWidgetCardPane != null) { - formWidgetCardPane.releaseResources(); - } - if (wsp != null) { - wsp.removeAll(); - } - designer.getSelectionModel().reset(); - formWidgetCardPane = null; - eventTable = null; - widgetPropertyTables = null; - mobileExtraPropertyPanes = null; - designer = null; - psp = null; - wsp = null; - tabsHeaderIconPane = null; - lastAffectedCreator = null; - this.removeAll(); - } - @Override protected String title4PopupWindow() { return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Control_Setting"); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/XCreateGather.java b/designer-form/src/main/java/com/fr/design/mainframe/XCreateGather.java new file mode 100644 index 000000000..42b957c83 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/XCreateGather.java @@ -0,0 +1,7 @@ +package com.fr.design.mainframe; + +import com.fr.design.designer.creator.XCreator; + +public interface XCreateGather { + void dealWith(XCreator xCreator); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java b/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java index 609e45b5d..3b9ee9ab4 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java @@ -14,7 +14,6 @@ import com.fr.design.designer.creator.XWTitleLayout; import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; import com.fr.design.dialog.AttrScrollPane; import com.fr.design.dialog.BasicScrollPane; -import com.fr.design.file.Releasable; import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; @@ -25,6 +24,7 @@ import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.EastRegionContainerPane; import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.JForm; +import com.fr.design.mainframe.JTemplate; import com.fr.design.widget.DataModify; import com.fr.design.widget.FormWidgetDefinePaneFactoryBase; import com.fr.design.widget.Operator; @@ -49,7 +49,7 @@ import java.awt.BorderLayout; /** * Created by ibm on 2017/7/25. */ -public class FormWidgetCardPane extends AbstractAttrNoScrollPane implements Releasable { +public class FormWidgetCardPane extends AbstractAttrNoScrollPane { private AttributeChangeListener listener; private FormDesigner designer; //当前的编辑器属性定义面板 @@ -67,10 +67,6 @@ public class FormWidgetCardPane extends AbstractAttrNoScrollPane implements Rele this.designer = designer; initComponents(); initDefinePane(); - widgetBoundPane = createWidgetBoundPane(xCreator); - if (widgetBoundPane != null) { - attriCardPane.add(widgetBoundPane, BorderLayout.CENTER); - } } public XLayoutContainer getParent(XCreator source) { @@ -162,10 +158,15 @@ public class FormWidgetCardPane extends AbstractAttrNoScrollPane implements Rele jPanel.add(uiExpandablePane, BorderLayout.NORTH); + widgetBoundPane = createWidgetBoundPane(xCreator); + if (widgetBoundPane != null) { + attriCardPane.add(widgetBoundPane, BorderLayout.NORTH); + } } private static void freshPropertyMode(XCreator xCreator) { - if (!(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate() instanceof JForm)) { + JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (!(jTemplate instanceof JForm) && jTemplate.isUpMode()) { if (xCreator instanceof XWParameterLayout) { EastRegionContainerPane.getInstance().switchMode(EastRegionContainerPane.PropertyMode.REPORT_PARA); } else { @@ -187,7 +188,7 @@ public class FormWidgetCardPane extends AbstractAttrNoScrollPane implements Rele JComponent jComponent = definePane.toSwingComponent(); - attriCardPane.add(jComponent, BorderLayout.NORTH); + attriCardPane.add(jComponent, BorderLayout.CENTER); currentEditorDefinePane = definePane; } @@ -232,7 +233,7 @@ public class FormWidgetCardPane extends AbstractAttrNoScrollPane implements Rele UITextField widgetNameField = widgetPropertyPane.getWidgetNameField(); String toSetWidgetName = widgetNameField.getText(); String currentWidgetName = widget.getWidgetName(); - boolean exist = designer.getTarget().isNameExist(toSetWidgetName) && !ComparatorUtils.equals(toSetWidgetName, currentWidgetName); + boolean exist = designer.getTarget().isNameExist(toSetWidgetName, widget) && !ComparatorUtils.equals(toSetWidgetName, currentWidgetName); if (toSetWidgetName.isEmpty()) { widgetNameField.setText(currentWidgetName); return; @@ -281,16 +282,4 @@ public class FormWidgetCardPane extends AbstractAttrNoScrollPane implements Rele public void firePropertyEdit() { designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED); } - - @Override - public void releaseResources() { - listener = null; - designer = null; - currentEditorDefinePane = null; - widgetPropertyPane = null; - attriCardPane = null; - xCreator = null; - widgetBoundPane = null; - this.removeAll(); - } } diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetAbsoluteBoundPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetAbsoluteBoundPane.java index 5604ef4be..e8aeb994d 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetAbsoluteBoundPane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetAbsoluteBoundPane.java @@ -9,8 +9,7 @@ import com.fr.design.utils.gui.LayoutUtils; import com.fr.design.widget.WidgetBoundsPaneFactory; import com.fr.form.ui.container.WLayout; - -import java.awt.Rectangle; +import java.awt.*; /** @@ -30,11 +29,13 @@ public class WidgetAbsoluteBoundPane extends WidgetBoundPane { y = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0d); width = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0d); height = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0d); + ratioLockedButton = new AspectRatioLockedButton(width, height); x.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Coords_And_Size")); y.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Coords_And_Size")); width.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Coords_And_Size")); height.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Coords_And_Size")); - this.add(WidgetBoundsPaneFactory.createAbsoluteBoundsPane(x, y, width, height, WidgetBoundsPaneFactory.NameAttribute.WIDGET)); + ratioLockedButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Coords_And_Size")); + this.add(WidgetBoundsPaneFactory.createAbsoluteBoundsPane(x, y, width, height, ratioLockedButton, WidgetBoundsPaneFactory.NameAttribute.WIDGET)); } @Override diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetBoundPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetBoundPane.java index ab148f2ae..bfcaeb60e 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetBoundPane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetBoundPane.java @@ -11,19 +11,34 @@ import com.fr.design.designer.creator.cardlayout.XWCardLayout; import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.event.GlobalNameListener; +import com.fr.design.event.GlobalNameObserver; +import com.fr.design.event.UIObserver; +import com.fr.design.event.UIObserverListener; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.gui.ispinner.UISpinner; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.FormDesigner; +import com.fr.design.mainframe.JForm; +import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.WidgetPropertyPane; import com.fr.design.utils.ComponentUtils; import com.fr.design.widget.WidgetBoundsPaneFactory; import com.fr.form.ui.PaddingMargin; +import com.fr.form.ui.Widget; import com.fr.form.ui.container.WFitLayout; import com.fr.form.ui.container.WLayout; +import com.fr.general.IOUtils; +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.basic.BasicButtonUI; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; -import javax.swing.JOptionPane; -import java.awt.Rectangle; +import static com.fr.design.i18n.Toolkit.i18nText; /** @@ -37,6 +52,7 @@ public class WidgetBoundPane extends BasicPane { protected XCreator creator; protected UISpinner width; protected UISpinner height; + protected AspectRatioLockedButton ratioLockedButton; public WidgetBoundPane(XCreator source) { this.setLayout(FRGUIPaneFactory.createBorderLayout()); @@ -59,13 +75,21 @@ public class WidgetBoundPane extends BasicPane { public void initBoundPane() { width = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0d); height = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0d); - width.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Coords_And_Size")); - height.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Coords_And_Size")); + width.setGlobalName(i18nText("Fine-Design_Form_Coords_And_Size")); + height.setGlobalName(i18nText("Fine-Design_Form_Coords_And_Size")); if (creator.acceptType(XWCardLayout.class)) { width.setEnabled(false); height.setEnabled(false); } - this.add(WidgetBoundsPaneFactory.createBoundsPane(width, height)); + + JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (jTemplate.isJWorkBook() || !((JForm)jTemplate).isSelectRootPane()) { + ratioLockedButton = new AspectRatioLockedButton(width, height); + ratioLockedButton.setGlobalName(i18nText("Fine-Design_Form_Coords_And_Size")); + ratioLockedButton.setLockEnabled(false); + } + + this.add(WidgetBoundsPaneFactory.createBoundsPane(width, height, ratioLockedButton)); } @@ -80,8 +104,15 @@ public class WidgetBoundPane extends BasicPane { public void populate() { Rectangle bounds = new Rectangle(creator.getBounds()); + if (ratioLockedButton != null) { + // 临时禁止尺寸比例锁定,关掉widthSpinner/heightSpinner之间的数值关联,以更新其高度和宽度值 + ratioLockedButton.setLocked(false); + } width.setValue(bounds.width); height.setValue(bounds.height); + if (ratioLockedButton != null) { + ratioLockedButton.populate(creator); + } } public void fix() { @@ -97,6 +128,9 @@ public class WidgetBoundPane extends BasicPane { if (bounds.height != h) { limitHeight(wabs, h, bounds, rec); } + if (ratioLockedButton != null) { + ratioLockedButton.update(creator); + } } @@ -116,11 +150,11 @@ public class WidgetBoundPane extends BasicPane { PaddingMargin margin = wabs.getMargin(); if (bounds.width != w) { if (bounds.width == rec.width - margin.getLeft() - margin.getRight()) { - FineJOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Beyond_Bounds")); + FineJOptionPane.showMessageDialog(null, i18nText("Fine-Design_Form_Beyond_Bounds")); width.setValue(bounds.width); return; } else if (w < minWidth) { - FineJOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Min_Width") + Integer.toString(minWidth)); + FineJOptionPane.showMessageDialog(null, i18nText("Fine-Design_Form_Min_Width") + Integer.toString(minWidth)); width.setValue(bounds.width); return; } @@ -137,11 +171,11 @@ public class WidgetBoundPane extends BasicPane { int minHeight = (int) (MINHEIGHT * ((WFitLayout) wabs).getResolutionScaling()); if (bounds.height != h) { if (bounds.height == rec.height - margin.getTop() - margin.getBottom()) { - FineJOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Beyond_Bounds")); + FineJOptionPane.showMessageDialog(null, i18nText("Fine-Design_Form_Beyond_Bounds")); height.setValue(bounds.height); return; } else if (h < minHeight) { - FineJOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Min_Height") + Integer.toString(minHeight)); + FineJOptionPane.showMessageDialog(null, i18nText("Fine-Design_Form_Min_Height") + Integer.toString(minHeight)); height.setValue(bounds.height); return; } @@ -165,4 +199,141 @@ public class WidgetBoundPane extends BasicPane { } + protected static class AspectRatioLockedButton extends JButton implements UIObserver, GlobalNameObserver { + + private final Icon enabledLocked = IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_lock_enabled.png"); + private final Icon disabledLocked = IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_lock_disabled.png"); + private final Icon enabledUnLocked = IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_unlock_enabled.png"); + private final Icon disabledUnLocked = IOUtils.readIcon("/com/fr/design/images/buttonicon/icon_unlock_disabled.png"); + + private UIObserverListener uiObserverListener; + private GlobalNameListener globalNameListener; + private String globalName = null; + + private final UISpinner mWidthSpinner; + private final UISpinner mHeightSpinner; + + protected double width4Backup = 0; + protected double height4Backup = 0; + + public AspectRatioLockedButton(UISpinner widthSpinner, UISpinner heightSpinner) { + setUI(new BasicButtonUI()); + setBorderPainted(false); + setBorder(null); + setContentAreaFilled(false); + setPreferredSize(new Dimension(24, 24)); + + this.mWidthSpinner = widthSpinner; + this.mHeightSpinner = heightSpinner; + + addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // 改变图标icon + setLocked(!isLocked()); + + if (isLocked() && isLockEnabled()) { + width4Backup = mWidthSpinner.getValue(); + height4Backup = mHeightSpinner.getValue(); + } + + if (globalNameListener != null) { + globalNameListener.setGlobalName(globalName); + } + + if (uiObserverListener != null) { + uiObserverListener.doChange(); + } + } + }); + + mWidthSpinner.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + if (isLockEnabled() && isLocked() && width4Backup > 0 && height4Backup > 0) { + mHeightSpinner.setValue(mWidthSpinner.getValue() * width4Backup / height4Backup, false); + } + } + }); + mHeightSpinner.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + if (isLockEnabled() && isLocked() && width4Backup > 0 && height4Backup > 0) { + mWidthSpinner.setValue(mHeightSpinner.getValue() * height4Backup / width4Backup, false); + } + } + }); + } + + @Override + public Icon getIcon() { + if (this.isLocked()) { + if (this.isLockEnabled()) { + return enabledLocked; + } else { + return disabledLocked; + } + } else { + if (this.isLockEnabled()) { + return enabledUnLocked; + } else { + return disabledUnLocked; + } + } + } + + public void setLocked(boolean locked) { + this.setSelected(locked); + } + + public boolean isLocked() { + return this.isSelected(); + } + + public boolean isLockEnabled() { + return this.isEnabled(); + } + + public void setLockEnabled(boolean enabled) { + this.setEnabled(enabled); + setToolTipText(isLockEnabled() ? null : i18nText("Fine-Design_Form_Widget_Lock_Aspect_Ratio_Button_ToolTip")); + } + + public void populate(XCreator creator) { + Rectangle bounds = new Rectangle(creator.getBounds()); + width4Backup = bounds.width; + height4Backup = bounds.height; + Widget widget = creator.toData(); + setLocked(widget.isAspectRatioLocked()); + } + + public void update(XCreator creator) { + creator.toData().setAspectRatioLocked(this.isLocked()); + } + + @Override + public void registerChangeListener(UIObserverListener listener) { + uiObserverListener = listener; + } + + @Override + public boolean shouldResponseChangeListener() { + return true; + } + + @Override + public void registerNameListener(GlobalNameListener listener) { + this.globalNameListener = listener; + } + + @Override + public boolean shouldResponseNameListener() { + return true; + } + + @Override + public void setGlobalName(String name) { + this.globalName = name; + } + } } diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/BorderStyleWidgetDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/BorderStyleWidgetDefinePane.java index dbe2735e3..fe6634b1f 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/BorderStyleWidgetDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/BorderStyleWidgetDefinePane.java @@ -5,6 +5,7 @@ import com.fr.design.designer.IntervalConstants; import com.fr.design.designer.creator.XCreator; import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.xpane.LayoutStylePane; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.widget.accessibles.AccessibleWLayoutBorderStyleEditor; @@ -20,7 +21,7 @@ import java.awt.*; * Created by kerry on 2017/8/29. */ public class BorderStyleWidgetDefinePane extends AbstractDataModify { - private AccessibleWLayoutBorderStyleEditor borderStyleEditor; + private LayoutStylePane stylePane; public BorderStyleWidgetDefinePane(XCreator xCreator) { super(xCreator); @@ -29,13 +30,10 @@ public class BorderStyleWidgetDefinePane extends AbstractDataModify ADAPT_LABEL_MAX_WIDTH ? ADAPT_LABEL_MAX_WIDTH : p; - double[] columnSize = {adaptLabelColumnWidth, f}; - int[][] rowCount = {{1, 1}, {1, 1}}; - JPanel northPane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")), layoutComboBox}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); - northPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0)); - - - - Component[][] components = new Component[][]{ - new Component[]{adaptLabel, adaptComboBoxPane}, - new Component[]{intervalLabel, componentIntervelPane} - }; - JPanel centerPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); - centerPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L5, 0, 0)); - jPanel.add(northPane, BorderLayout.NORTH); - jPanel.add(centerPane, BorderLayout.CENTER); - return jPanel; + JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane( + new Component[][]{ + {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")), layoutComboBox}, + {adaptLabel, adaptComboBoxPane}, + {intervalLabel, componentIntervelPane} + }, + TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); + contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); + containerPane.add(contentPane, BorderLayout.CENTER); + + return containerPane; } @@ -154,7 +157,7 @@ public class FRFitLayoutDefinePane extends AbstractFRLayoutDefinePane { - private AccessibleCardTagWLayoutBorderStyleEditor accessibleCardTagWLayoutBorderStyleEditor; + private CardTagLayoutStylePane stylePane; private UICheckBox setCarousel; private UISpinner carouselInterval; private JPanel IntervalPane; @@ -39,11 +41,8 @@ public class WCardMainLayoutDefinePane extends AbstractDataModify extends AbstractDataModify { - private AccessibleWLayoutBorderStyleEditor borderStyleEditor; + private LayoutStylePane stylePane; public WTitleLayoutDefinePane(XCreator xCreator) { super(xCreator); @@ -34,18 +27,8 @@ public abstract class WTitleLayoutDefinePane> ERROR_CACHE = CacheBuilder.newBuilder() .maximumSize(DEFAULT_MAX_CACHE_SIZE) @@ -46,6 +51,21 @@ public class DesignerAppUtils { .concurrencyLevel(DEFAULT_CONCURRENCY_LEVEL) .build(); + public static void initPluginAllActiveListener() { + PluginListenerRegistration.getInstance().listen(PluginEventType.BeforeAllStop, new PluginEventListener() { + @Override + public void on(PluginEvent event) { + enablePluginTipDialog = false; + } + }); + PluginListenerRegistration.getInstance().listen(PluginEventType.AfterAllActive, new PluginEventListener() { + @Override + public void on(PluginEvent event) { + enablePluginTipDialog = true; + } + }); + } + /** * 弹出指定的插件信息, * 并失效缓存 @@ -77,7 +97,7 @@ public class DesignerAppUtils { * @return 格式化后的多行插件错误信息详情 */ public static String dealWithErrorDetailMultiLineAndCache(String key) { - if (!DesignerEnvManager.getEnvManager().isShowTemplateMissingPlugin()) { + if (!DesignerEnvManager.getEnvManager().isShowTemplateMissingPlugin() || !enablePluginTipDialog) { // 直接清空不提示 TemplateIOErrorContextHolder.reset(); return StringUtils.EMPTY; 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 45c2fea61..14895e90b 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 @@ -293,10 +293,13 @@ public class FormElementCaseDesigner /** * 移除选择 */ + @Override public void removeSelection() { TemplateElementCase templateElementCase = this.elementCasePane.getEditingElementCase(); if (templateElementCase instanceof WorkSheet) { ((WorkSheet) templateElementCase).setPaintSelection(false); + } else if (templateElementCase instanceof FormElementCase) { + this.elementCasePane.setSelection(new CellSelection(0, 0, 0, 0)); } elementCasePane.repaint(); } 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 b0f91a902..b6dc8bc4a 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java +++ b/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java @@ -75,6 +75,8 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous private int resolution = ScreenResolution.getScreenResolution(); + private int[] resizingBackupBounds = null; + protected GridMouseAdapter(Grid grid) { this.grid = grid; } @@ -338,6 +340,7 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous } boolean isControlDown = InputEventBaseOnOS.isControlDown(evt); + boolean isShiftDown = evt.isShiftDown(); long systemCurrentTime = System.currentTimeMillis(); if (systemCurrentTime - lastMouseMoveTime <= DRAG_REFRESH_TIME) {// alex:Drag @@ -351,10 +354,10 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous return; } - doWithMouseDragged(evt.getX(), evt.getY(), isControlDown); + doWithMouseDragged(evt.getX(), evt.getY(), isControlDown, isShiftDown); } - private void doWithMouseDragged(int evtX, int evtY, boolean isControlDown) { + private void doWithMouseDragged(int evtX, int evtY, boolean isControlDown, boolean isShiftDown) { ElementCasePane reportPane = grid.getElementCasePane(); if (reportPane.mustInVisibleRange()) { @@ -366,7 +369,7 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous Selection selection = reportPane.getSelection(); if (selection instanceof FloatSelection && !DesignerMode.isAuthorityEditing()) { - doWithFloatElementDragged(evtX, evtY, (FloatSelection) selection); + doWithFloatElementDragged(evtX, evtY, (FloatSelection) selection, isShiftDown); grid.setDragType(GridUtils.DRAG_FLOAT); } else if (grid.getDragType() == GridUtils.DRAG_CELLSELECTION_BOTTOMRIGHT_CORNER && !DesignerMode.isAuthorityEditing()) { doWithCellElementDragged(evtX, evtY, (CellSelection) selection); @@ -391,36 +394,83 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous * @param fs */ - private void doWithFloatElementDragged(int evtX, int evtY, FloatSelection fs) { + private void doWithFloatElementDragged(int evtX, int evtY, FloatSelection fs, boolean aspectRatio) { ElementCase report = grid.getElementCasePane().getEditingElementCase(); // int resolution = ScreenResolution.getScreenResolution(); String floatName = fs.getSelectedFloatName(); FloatElement floatElement = report.getFloatElement(floatName); int cursorType = grid.getCursor().getType(); + int currentLeft = Math.min(oldEvtX, evtX); + int currentTop = Math.min(oldEvtY, evtY); + int currentRight = Math.max(oldEvtX, evtX); + int currentBottom = Math.max(oldEvtY, evtY); + int currentWidth = currentRight - currentLeft; + int currentHeight = currentBottom - currentTop; + + int backupWidth= resizingBackupBounds[2]; + int backupHeight= resizingBackupBounds[3]; + if (cursorType == Cursor.NW_RESIZE_CURSOR || cursorType == Cursor.NE_RESIZE_CURSOR || cursorType == Cursor.SE_RESIZE_CURSOR || cursorType == Cursor.SW_RESIZE_CURSOR) { + if (aspectRatio) { + double currentDiagonal = Math.pow(currentWidth, 2) + Math.pow(currentHeight, 2); + double backupDiagonal = Math.pow(backupWidth, 2) + Math.pow(backupHeight, 2); + + int newWidth = (int) (Math.sqrt((currentDiagonal / backupDiagonal) * (Math.pow(backupWidth, 2)))); + int newHeight = (int) (Math.sqrt((currentDiagonal / backupDiagonal) * (Math.pow(backupHeight, 2)))); + + if (cursorType == Cursor.NW_RESIZE_CURSOR) { + currentLeft = currentRight - newWidth; + currentTop = currentBottom - newHeight; + } else if (cursorType == Cursor.NE_RESIZE_CURSOR) { + currentRight = currentLeft + newWidth; + currentTop = currentBottom - newHeight; + } else if (cursorType == Cursor.SW_RESIZE_CURSOR) { + currentLeft = currentRight - newWidth; + currentBottom = currentTop + newHeight; + } else if (cursorType == Cursor.SE_RESIZE_CURSOR){ + currentRight = currentLeft + newWidth; + currentBottom = currentTop + newHeight; + } + } + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); - FU floatX1_fu = FU.valueOfPix(Math.min(oldEvtX, evtX), resolution); - FU floatY1_fu = FU.valueOfPix(Math.min(oldEvtY, evtY), resolution); + + FU floatX1_fu = FU.valueOfPix(currentLeft, resolution); + FU floatY1_fu = FU.valueOfPix(currentTop, resolution); FU leftDistance = floatX1_fu.add(columnWidthList.getRangeValue(0, grid.getHorizontalValue())); FU topDistance = floatY1_fu.add(rowHeightList.getRangeValue(0, grid.getVerticalValue())); floatElement.setLeftDistance(leftDistance); floatElement.setTopDistance(topDistance); - floatElement.setWidth(FU.valueOfPix(Math.max(oldEvtX, evtX), resolution).subtract(floatX1_fu)); - floatElement.setHeight(FU.valueOfPix(Math.max(oldEvtY, evtY), resolution).subtract(floatY1_fu)); + floatElement.setWidth(FU.valueOfPix(currentRight, resolution).subtract(floatX1_fu)); + floatElement.setHeight(FU.valueOfPix(currentBottom, resolution).subtract(floatY1_fu)); } else if (cursorType == Cursor.S_RESIZE_CURSOR || cursorType == Cursor.N_RESIZE_CURSOR) { DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); - FU floatY1_fu = FU.valueOfPix(Math.min(oldEvtY, evtY), resolution); + FU floatY1_fu = FU.valueOfPix(currentTop, resolution); FU topDistance = floatY1_fu.add(rowHeightList.getRangeValue(0, grid.getVerticalValue())); floatElement.setTopDistance(topDistance); - floatElement.setHeight(FU.valueOfPix(Math.max(oldEvtY, evtY), resolution).subtract(floatY1_fu)); + floatElement.setHeight(FU.valueOfPix(currentBottom, resolution).subtract(floatY1_fu)); + + if (aspectRatio) { + currentWidth = backupWidth * currentHeight / backupHeight; + currentRight = currentLeft + currentWidth; + FU floatX1_fu = FU.valueOfPix(currentLeft, resolution); + floatElement.setWidth(FU.valueOfPix(currentRight, resolution).subtract(floatX1_fu)); + } } else if (cursorType == Cursor.W_RESIZE_CURSOR || cursorType == Cursor.E_RESIZE_CURSOR) { DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); - FU floatX1_fu = FU.valueOfPix(Math.min(oldEvtX, evtX), resolution); + FU floatX1_fu = FU.valueOfPix(currentLeft, resolution); FU leftDistance = floatX1_fu.add(columnWidthList.getRangeValue(0, grid.getHorizontalValue())); floatElement.setLeftDistance(leftDistance); - floatElement.setWidth(FU.valueOfPix(Math.max(oldEvtX, evtX), resolution).subtract(floatX1_fu)); + floatElement.setWidth(FU.valueOfPix(currentRight, resolution).subtract(floatX1_fu)); + + if (aspectRatio) { + currentHeight = backupHeight * currentWidth / backupWidth; + currentBottom = currentTop + currentHeight; + FU floatY1_fu = FU.valueOfPix(currentTop, resolution); + floatElement.setHeight(FU.valueOfPix(currentBottom, resolution).subtract(floatY1_fu)); + } } else if (cursorType == Cursor.MOVE_CURSOR) { DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); @@ -799,6 +849,13 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous } else if (cursorType == Cursor.E_RESIZE_CURSOR) { setOld_X_AndOld_Y(floatArray[0], floatArray[1]); } + + if (Cursor.SW_RESIZE_CURSOR <= cursorType && cursorType <= Cursor.E_RESIZE_CURSOR) { + resizingBackupBounds = new int[] { + (int) floatArray[0], (int)floatArray[1], + (int) floatArray[2] - (int) floatArray[0], (int) floatArray[3] - (int) floatArray[1] + }; + } } private void setOld_X_AndOld_Y(double x, double y) { diff --git a/designer-realize/src/main/java/com/fr/start/MainDesigner.java b/designer-realize/src/main/java/com/fr/start/MainDesigner.java index 5c8c57987..dd49f1b1a 100644 --- a/designer-realize/src/main/java/com/fr/start/MainDesigner.java +++ b/designer-realize/src/main/java/com/fr/start/MainDesigner.java @@ -42,6 +42,7 @@ import com.fr.design.monitor.DesignerLifecycleMonitorContext; import com.fr.design.share.SharableManager; import com.fr.design.utils.concurrent.ThreadFactoryBuilder; import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.env.utils.DesignerInteractionHistory; import com.fr.event.Event; import com.fr.event.EventDispatcher; import com.fr.event.Listener; @@ -512,6 +513,9 @@ public class MainDesigner extends BaseDesigner { InformationCollector collector = InformationCollector.getInstance(); collector.collectStopTime(); collector.saveXMLFile(); + + DesignerInteractionHistory historyCollector = DesignerInteractionHistory.getInstance(); + historyCollector.saveXMLFile(); } } diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerInitActivator.java b/designer-realize/src/main/java/com/fr/start/module/DesignerInitActivator.java index ebea410bb..1c8fee379 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerInitActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerInitActivator.java @@ -1,6 +1,7 @@ package com.fr.start.module; import com.fr.design.PluginClassRefreshManager; +import com.fr.design.mainframe.app.DesignerAppUtils; import com.fr.module.Activator; import com.fr.start.DesignerInitial; @@ -17,6 +18,7 @@ public class DesignerInitActivator extends Activator { @Override public void start() { PluginClassRefreshManager.getInstance().load(); + DesignerAppUtils.initPluginAllActiveListener(); DesignerInitial.init(findSingleton(StartupArgs.class).get()); }