diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java b/designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java index 381a9cd761..a9321879c8 100644 --- a/designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java @@ -24,6 +24,16 @@ public abstract class AbstractAttrNoScrollPane extends BasicPane { private AttributeChangeListener listener; private String globalName = ""; + private boolean autoFireAttributesChanged = true; + + public boolean isAutoFireAttributesChanged() { + return this.autoFireAttributesChanged; + } + + public void setAutoFireAttributesChanged(boolean autoFireAttributesChanged) { + this.autoFireAttributesChanged = autoFireAttributesChanged; + } + protected AbstractAttrNoScrollPane() { initAll(); } @@ -127,7 +137,9 @@ public abstract class AbstractAttrNoScrollPane extends BasicPane { public void attributeChanged() { synchronized (this) { if (listener != null) { - listener.attributeChange(); + if (autoFireAttributesChanged) { + listener.attributeChange(); + } } } } diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/AttributeChangeUtils.java b/designer-base/src/main/java/com/fr/design/gui/frpane/AttributeChangeUtils.java new file mode 100644 index 0000000000..bfc1ff9d45 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/AttributeChangeUtils.java @@ -0,0 +1,47 @@ +package com.fr.design.gui.frpane; + +import java.awt.Component; +import java.awt.Container; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/17 + */ +public class AttributeChangeUtils { + private static AbstractAttrNoScrollPane findNearestAttrNoScrollPaneAncestor(Component c) { + for(Container p = c.getParent(); p != null; p = p.getParent()) { + if (p instanceof AbstractAttrNoScrollPane) { + return (AbstractAttrNoScrollPane) p; + } + } + return null; + } + + public static void changeComposedUI(Component composedComponent, boolean fireMiddleStateChanged, UIChangeAction action) { + AbstractAttrNoScrollPane attrPane = findNearestAttrNoScrollPaneAncestor(composedComponent); + boolean oldAutoFire = true; + + if (!fireMiddleStateChanged) { + // 禁止属性面板自动处理属性更新 + if (attrPane != null) { + oldAutoFire = attrPane.isAutoFireAttributesChanged(); + attrPane.setAutoFireAttributesChanged(false); + } + } + + // 更新UI + action.changeComposedUI(); + + if (!fireMiddleStateChanged) { + // 恢复属性面板自动处理属性更新 + if (attrPane != null) { + attrPane.setAutoFireAttributesChanged(oldAutoFire); + } + } + } + + public interface UIChangeAction { + void changeComposedUI(); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/gui/style/FollowingThemePane.java b/designer-base/src/main/java/com/fr/design/gui/style/FollowingThemePane.java index 2d596d612e..bf06aa2fd7 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/FollowingThemePane.java +++ b/designer-base/src/main/java/com/fr/design/gui/style/FollowingThemePane.java @@ -5,6 +5,7 @@ import com.fr.design.dialog.BasicPane; import com.fr.design.event.UIObserver; import com.fr.design.event.UIObserverListener; import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.gui.frpane.AttributeChangeUtils; import com.fr.design.gui.ibutton.UIButtonGroup; import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; @@ -52,12 +53,15 @@ public class FollowingThemePane extends BasicPane implements UIObserver { followingThemeButtonGroup.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - for (FollowingThemeActionChangeListener changeListener : changeListeners) { - changeListener.onFollowingTheme(isFollowingTheme()); - } - invalidate(); - - // 与主题相关的属性面板更新完毕后,再通知外层更新数据 + AttributeChangeUtils.changeComposedUI(FollowingThemePane.this, false, new AttributeChangeUtils.UIChangeAction() { + @Override + public void changeComposedUI() { + for (FollowingThemeActionChangeListener changeListener : changeListeners) { + changeListener.onFollowingTheme(isFollowingTheme()); + } + invalidate(); + } + }); if (uiObserverListener != null) { uiObserverListener.doChange(); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java index d5019310a1..bfd335f392 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java @@ -6,6 +6,7 @@ import com.fr.design.designer.IntervalConstants; import com.fr.design.dialog.BasicPane; import com.fr.design.event.UIObserver; import com.fr.design.event.UIObserverListener; +import com.fr.design.gui.frpane.AttributeChangeUtils; import com.fr.design.gui.ibutton.UIButtonGroup; import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; @@ -73,27 +74,13 @@ public class StylePane extends BasicPane implements UIObserver { followingThemeButtonGroup.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - int selectedIndex = followingThemeButtonGroup.getSelectedIndex(); - cardLayout.show(contentPane, FOLLOWING_THEME_STRING_ARRAYS[selectedIndex]); - if (selectedIndex == 1) { - // 对于同一个单元格,跟随主题切换到自定义,自定义中的配置与其保持一致 - NameStyle lastSelectedNameStyle = themedCellStyleListPane.updateBean(); - if (lastSelectedNameStyle != null) { - Style lastSelectedRealStyle = lastSelectedNameStyle.getRealStyle(); - try { - lastSelectedRealStyle = (Style) lastSelectedRealStyle.clone(); - if (lastSelectedRealStyle != null) { - customStylePane.populateBean(lastSelectedRealStyle); - } - } catch (CloneNotSupportedException ex) { - FineLoggerFactory.getLogger().error(ex.getMessage(), ex); - } + AttributeChangeUtils.changeComposedUI(StylePane.this, false, new AttributeChangeUtils.UIChangeAction() { + @Override + public void changeComposedUI() { + int selectedIndex = followingThemeButtonGroup.getSelectedIndex(); + onFollowingThemeSettingChanged(selectedIndex, selectedIndex == 0); } - } else { - // 对于同一个单元格,自定义切换到跟随主题,跟随主题选中"默认"样式,并使用默认样式设置选中的单元格 - themedCellStyleListPane.reset(); - } - + }); fireStateChanged(); } }); @@ -109,6 +96,28 @@ public class StylePane extends BasicPane implements UIObserver { IntervalConstants.INTERVAL_L1, 0); } + private void onFollowingThemeSettingChanged(int selectedIndex, boolean isFollowingTheme) { + cardLayout.show(contentPane, FOLLOWING_THEME_STRING_ARRAYS[selectedIndex]); + if (!isFollowingTheme) { + // 对于同一个单元格,跟随主题切换到自定义,自定义中的配置与其保持一致 + NameStyle lastSelectedNameStyle = themedCellStyleListPane.updateBean(); + if (lastSelectedNameStyle != null) { + Style lastSelectedRealStyle = lastSelectedNameStyle.getRealStyle(); + try { + lastSelectedRealStyle = (Style) lastSelectedRealStyle.clone(); + if (lastSelectedRealStyle != null) { + customStylePane.populateBean(lastSelectedRealStyle); + } + } catch (CloneNotSupportedException ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } + } + } else { + // 对于同一个单元格,自定义切换到跟随主题,跟随主题选中"默认"样式,并使用默认样式设置选中的单元格 + themedCellStyleListPane.reset(); + } + } + protected JPanel createTabbedContentPane() { JPanel contentPane = new JPanel(cardLayout) { @Override