diff --git a/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java b/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java index 5ddd44b60..193a95d3f 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java @@ -23,6 +23,7 @@ import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.DesignerContext; import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.design.utils.gui.UIComponentUtils; import com.fr.general.ComparatorUtils; import com.fr.general.FRFont; import com.fr.general.Inter; @@ -32,8 +33,17 @@ import com.fr.third.apache.log4j.Level; import com.fr.transaction.Configurations; import com.fr.transaction.Worker; -import javax.swing.*; -import java.awt.*; +import javax.swing.BorderFactory; +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; @@ -473,7 +483,7 @@ public class PreferencePane extends BasicPane { JPanel memoryPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Caching_Template")); UILabel memoryLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Max_Caching_Template")); UILabel memoryTipLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Caching_Template_Tip")); - memoryTipLabel.setLineWrap(MEMORY_TIP_LABEL_MAX_WIDTH); + UIComponentUtils.setLineWrap(memoryTipLabel, MEMORY_TIP_LABEL_MAX_WIDTH); memoryTipLabel.setBorder(BorderFactory.createEmptyBorder(0, CACHING_GAP, 0, 0)); cachingTemplateSpinner = new UISpinner(0, CACHING_MAX, 1, CACHING_DEFAULT); JPanel memorySpace = new JPanel(FRGUIPaneFactory.createLeftZeroLayout()); diff --git a/designer-base/src/main/java/com/fr/design/gui/core/UITextComponent.java b/designer-base/src/main/java/com/fr/design/gui/core/UITextComponent.java new file mode 100644 index 000000000..0cf2e1c3c --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/core/UITextComponent.java @@ -0,0 +1,10 @@ +package com.fr.design.gui.core; + +/** + * 这个接口说明一个基本组件可以设置文本 + * Created by plough on 2019/1/11. + */ +public interface UITextComponent { + String getText(); + void setText(String text); +} diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButton.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButton.java index d70f06ea6..078bf692b 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButton.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButton.java @@ -6,6 +6,7 @@ import com.fr.base.GraphHelper; import com.fr.design.constants.UIConstants; import com.fr.design.event.UIObserver; import com.fr.design.event.UIObserverListener; +import com.fr.design.gui.core.UITextComponent; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.stable.Constants; import com.fr.stable.StringUtils; @@ -28,7 +29,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.RoundRectangle2D; -public class UIButton extends JButton implements UIObserver { +public class UIButton extends JButton implements UIObserver, UITextComponent { private static final int TOOLTIP_INIT_DELAY = 300; // 延迟 0.3s 显示提示文字 public static final int OTHER_BORDER = 1; @@ -49,7 +50,6 @@ public class UIButton extends JButton implements UIObserver { private CellBorderStyle border = null; protected UIObserverListener uiObserverListener; - private boolean fixedHeight = true; // 是否将按钮的高度固定为 HEIGHT public UIButton() { this(StringUtils.EMPTY); @@ -340,36 +340,13 @@ public class UIButton extends JButton implements UIObserver { this.isBorderPaintedOnlyWhenPressed = value; } - /** - * 到达指定宽度后换行 - */ - public void setLineWrap(int width) { - insertPrefixToText(""); - } - - /** - * 自动换行 - */ - public void setLineWrap() { - insertPrefixToText(""); - } - - private void insertPrefixToText(String prefix) { + private boolean isFixedHeight() { String text = this.getText(); if (StringUtils.isEmpty(text)) { - return; + return true; } - this.setText(prefix + text); - // 如果文本过长,且允许换行的话,需要放开按钮高度的限制 - this.setFixedHeight(false); - } - - private boolean isFixedHeight() { - return fixedHeight; - } - - private void setFixedHeight(boolean fixedHeight) { - this.fixedHeight = fixedHeight; + // 如果允许换行,需要放开按钮高度的限制 + return !text.startsWith(""); } /** diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java index c9771b766..edbc01340 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java @@ -3,6 +3,7 @@ package com.fr.design.gui.ibutton; import com.fr.base.BaseUtils; import com.fr.design.constants.UIConstants; import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.design.utils.gui.UIComponentUtils; import javax.swing.Icon; import javax.swing.JFrame; @@ -139,7 +140,7 @@ public class UIHeadGroup extends JPanel { labelButton.setRoundBorder(false); labelButton.setBorderPainted(false); labelButton.setPressedPainted(false); - labelButton.setLineWrap(); + UIComponentUtils.setLineWrap(labelButton); labelButtonList.add(labelButton); this.add(labelButton); } diff --git a/designer-base/src/main/java/com/fr/design/gui/ilable/UILabel.java b/designer-base/src/main/java/com/fr/design/gui/ilable/UILabel.java index 09e7ef0a7..d6a795275 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ilable/UILabel.java +++ b/designer-base/src/main/java/com/fr/design/gui/ilable/UILabel.java @@ -1,9 +1,9 @@ package com.fr.design.gui.ilable; +import com.fr.design.gui.core.UITextComponent; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.stable.StringUtils; -import com.fr.stable.StringUtils; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.JLabel; @@ -19,7 +19,7 @@ import java.awt.Dimension; * Date: 13-1-23 * Time: 下午3:15 */ -public class UILabel extends JLabel { +public class UILabel extends JLabel implements UITextComponent { private static final int HTML_SHIFT_HEIGHT = 3; public UILabel(String text, Icon image, int horizontalAlignment) { @@ -64,29 +64,6 @@ public class UILabel extends JLabel { return preferredSize; } - /** - * 到达指定宽度后换行 - */ - public void setLineWrap(int width) { - insertPrefixToText(""); - } - - /** - * 自动换行 - */ - public void setLineWrap() { - insertPrefixToText(""); - } - - private void insertPrefixToText(String prefix) { - String text = this.getText(); - if (StringUtils.isEmpty(text)) { - return; - } - this.setText(prefix + text); - } - - public static void main(String[] args) { // UILabel label = new UILabel("shishi",SwingConstants.LEFT); JFrame frame = new JFrame("Test"); diff --git a/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBackgroundPane.java b/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBackgroundPane.java index 18c458963..a2f6e70d6 100644 --- a/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBackgroundPane.java +++ b/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBackgroundPane.java @@ -5,6 +5,7 @@ import com.fr.design.gui.ibutton.UIRadioButton; import com.fr.design.gui.ilable.UILabel; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.style.background.BackgroundDetailPane; +import com.fr.design.utils.gui.UIComponentUtils; import com.fr.general.Background; import javax.swing.BorderFactory; @@ -43,7 +44,7 @@ public class GradientBackgroundPane extends BackgroundDetailPane { blankJp.add(gradientBar); UILabel jl = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Drag_To_Select_Gradient")); jl.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 20)); - jl.setLineWrap(); + UIComponentUtils.setLineWrap(jl); jl.setHorizontalAlignment(SwingConstants.CENTER); gradientPanel.add(jl, BorderLayout.NORTH); gradientPanel.add(blankJp, BorderLayout.SOUTH); diff --git a/designer-base/src/main/java/com/fr/design/utils/gui/GUICoreUtils.java b/designer-base/src/main/java/com/fr/design/utils/gui/GUICoreUtils.java index 21af9365d..c8c0561c9 100644 --- a/designer-base/src/main/java/com/fr/design/utils/gui/GUICoreUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/gui/GUICoreUtils.java @@ -6,7 +6,13 @@ package com.fr.design.utils.gui; import com.fr.base.BaseUtils; import com.fr.base.Style; import com.fr.base.background.ColorBackground; -import com.fr.data.util.function.*; +import com.fr.data.util.function.AverageFunction; +import com.fr.data.util.function.CountFunction; +import com.fr.data.util.function.DataFunction; +import com.fr.data.util.function.MaxFunction; +import com.fr.data.util.function.MinFunction; +import com.fr.data.util.function.NoneFunction; +import com.fr.data.util.function.SumFunction; import com.fr.design.actions.UpdateAction; import com.fr.design.actions.core.ActionFactory; import com.fr.design.border.UITitledBorder; @@ -25,20 +31,48 @@ import com.fr.design.style.color.ColorFactory; import com.fr.design.style.color.ColorSelectBox; import com.fr.design.style.color.ColorSelectable; import com.fr.general.FRFont; - import com.fr.stable.Constants; import com.fr.stable.OperatingSystem; import com.fr.stable.StringUtils; -import javax.swing.*; +import javax.swing.AbstractButton; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.DefaultListModel; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JFormattedTextField; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JSeparator; +import javax.swing.JSlider; +import javax.swing.JSpinner; +import javax.swing.JTree; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.LineBorder; import javax.swing.border.TitledBorder; import javax.swing.event.ChangeListener; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; - -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.Window; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; @@ -48,16 +82,17 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -public abstract class GUICoreUtils{ +// Noninstantiable utility class +public final class GUICoreUtils { private static final int WINDOW_GAP = 20; private static final int HEIGHT_GAP = 28; private static final int WIN_LOCATION_Y=23; private static final int CASE_FOUR = 4; - - + // 覆盖缺省构造器,不可实例化 private GUICoreUtils() { + throw new AssertionError(); } /** diff --git a/designer-base/src/main/java/com/fr/design/utils/gui/UIComponentUtils.java b/designer-base/src/main/java/com/fr/design/utils/gui/UIComponentUtils.java new file mode 100644 index 000000000..676369e75 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/utils/gui/UIComponentUtils.java @@ -0,0 +1,51 @@ +package com.fr.design.utils.gui; + +import com.fr.design.gui.core.UITextComponent; +import com.fr.stable.StringUtils; + +/** + * 包含 UI 组件相关的工具方法 + * Created by plough on 2019/1/11. + */ + +// Noninstantiable utility class +public class UIComponentUtils { + private static final String HTML_TAG_TPL = ""; + private static final String HTML_BODY_TAG = ""; + private static final String HTML_TAG = ""; + private static final int MIN_WIDTH = 10; + + // 覆盖缺省构造器,不可实例化 + private UIComponentUtils() { + throw new AssertionError(); + } + + /** + * 到达指定宽度后换行 + */ + public static void setLineWrap(UITextComponent comp, int width) { + if (width < MIN_WIDTH) { + width = MIN_WIDTH; + } + insertPrefixToText(comp, String.format(HTML_TAG_TPL, width)); + } + + /** + * 自动换行 + */ + public static void setLineWrap(UITextComponent comp) { + insertPrefixToText(comp, HTML_BODY_TAG); + } + + private static void insertPrefixToText(UITextComponent comp, String prefix) { + if (comp == null) { + return; + } + String text = comp.getText(); + + if (StringUtils.isEmpty(comp.getText()) || text.startsWith(HTML_TAG)) { + return; + } + comp.setText(prefix + comp.getText()); + } +} diff --git a/designer-base/src/test/java/com/fr/design/utils/gui/UIComponentUtilsTest.java b/designer-base/src/test/java/com/fr/design/utils/gui/UIComponentUtilsTest.java new file mode 100644 index 000000000..256abeeca --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/utils/gui/UIComponentUtilsTest.java @@ -0,0 +1,109 @@ +package com.fr.design.utils.gui; + +import com.fr.design.gui.core.UITextComponent; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.stable.StringUtils; +import org.junit.Before; +import org.junit.Test; + +import javax.swing.Icon; + +import java.awt.Component; +import java.awt.Graphics; + +import static org.junit.Assert.*; + +/** + * Created by plough on 2019/1/11. + */ +public class UIComponentUtilsTest { + private static final String HTML_TAG_TPL = ""; + private static final String HTML_TAG = ""; + private UIButton textButton; + private UIButton emptyTextButton; + private UIButton iconButton; + + private UILabel textLabel; + private UILabel emptyTextLabel; + private UILabel iconLabel; + + @Before + public void setUp() { + textButton = new UIButton("hello"); + emptyTextButton = new UIButton(StringUtils.EMPTY); + iconButton = new UIButton(createMockIcon()); + + textLabel = new UILabel("hello"); + emptyTextLabel = new UILabel(StringUtils.EMPTY); + iconLabel = new UILabel(createMockIcon()); + } + + @Test + public void testSetLineWrap() { + UITextComponent[] noWrapComps = {emptyTextButton, emptyTextLabel, iconButton, iconLabel}; + UITextComponent[] wrapComps = {textLabel, textButton}; + + for (UITextComponent comp : wrapComps) { + UIComponentUtils.setLineWrap(comp); + assertTrue(isLineWrapped(comp)); + } + + for (UITextComponent comp : noWrapComps) { + UIComponentUtils.setLineWrap(comp); + assertFalse(isLineWrapped(comp)); + } + } + + @Test + public void testSetLineWrapWithLineWidth() { + UILabel label1 = new UILabel("l1"); + UILabel label2 = new UILabel("l2"); + UILabel label3 = new UILabel("l3"); + UIComponentUtils.setLineWrap(label1, 50); + assertTrue(isLineWrappedWithLineWidth(label1, 50)); + + UIComponentUtils.setLineWrap(label2, 0); + assertTrue(isLineWrappedWithLineWidth(label2, 10)); + + UIComponentUtils.setLineWrap(label3, -10); + assertTrue(isLineWrappedWithLineWidth(label3, 10)); + } + + @Test + public void testAddHtmlTwice() { + UIComponentUtils.setLineWrap(textLabel, 50); + UIComponentUtils.setLineWrap(textLabel, 20); // 第二次应该不生效 + assertTrue(isLineWrappedWithLineWidth(textLabel, 50)); + } + + private boolean isLineWrapped(UITextComponent comp) { + String text = comp.getText(); + return StringUtils.isNotEmpty(text) && text.startsWith(HTML_TAG); + } + + private boolean isLineWrappedWithLineWidth(UITextComponent comp, int width) { + String text = comp.getText(); + return StringUtils.isNotEmpty(text) && text.startsWith(String.format(HTML_TAG_TPL, width)); + } + + + private Icon createMockIcon() { + return new Icon() { + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + // do nothing + } + + @Override + public int getIconWidth() { + return 0; + } + + @Override + public int getIconHeight() { + return 0; + } + }; + } +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java index aa8e72853..b58456be7 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java @@ -17,6 +17,7 @@ import com.fr.design.layout.TableLayoutHelper; import com.fr.design.layout.VerticalFlowLayout; import com.fr.design.mainframe.EastRegionContainerPane; import com.fr.design.mainframe.JTemplate; +import com.fr.design.utils.gui.UIComponentUtils; import com.fr.general.ComparatorUtils; import com.fr.report.cell.DefaultTemplateCellElement; import com.fr.report.cell.TemplateCellElement; @@ -200,7 +201,7 @@ public class CellOtherSetPane extends AbstractCellAttrPane { UILabel showContentLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Show_Content"), SwingConstants.LEFT); UILabel toolTipLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_ToolTip")); - toolTipLabel.setLineWrap(); + UIComponentUtils.setLineWrap(toolTipLabel); JPanel toolTipTextFieldWrapper = new JPanel(new BorderLayout()); toolTipTextFieldWrapper.add(tooltipTextField, BorderLayout.NORTH); diff --git a/designer-realize/src/main/java/com/fr/design/report/WriteShortCutsPane.java b/designer-realize/src/main/java/com/fr/design/report/WriteShortCutsPane.java index fa1948e9d..8cf891b92 100644 --- a/designer-realize/src/main/java/com/fr/design/report/WriteShortCutsPane.java +++ b/designer-realize/src/main/java/com/fr/design/report/WriteShortCutsPane.java @@ -6,6 +6,7 @@ import com.fr.config.ServerPreferenceConfig; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.utils.gui.UIComponentUtils; import com.fr.general.ComparatorUtils; import javax.swing.BorderFactory; @@ -69,7 +70,7 @@ public class WriteShortCutsPane extends JPanel{ UILabel nextCol = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Cursor_To_Next_Column"), SwingConstants.CENTER); UILabel nextRow = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Cursor_To_Next_Row"), SwingConstants.CENTER); UILabel shortName = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Current_Keys"), SwingConstants.CENTER); - shortName.setLineWrap(MAX_LABEL_WIDTH); + UIComponentUtils.setLineWrap(shortName, MAX_LABEL_WIDTH); nextColHK = new UILabel(nextColString, SwingConstants.CENTER); JPanel switchBtnPane = getSwitchBtnPane(); nextRowHK = new UILabel(nextRowString, SwingConstants.CENTER); diff --git a/designer-realize/src/main/java/com/fr/design/webattr/WebCssPane.java b/designer-realize/src/main/java/com/fr/design/webattr/WebCssPane.java index 6f9866605..1f8ba57bb 100644 --- a/designer-realize/src/main/java/com/fr/design/webattr/WebCssPane.java +++ b/designer-realize/src/main/java/com/fr/design/webattr/WebCssPane.java @@ -6,6 +6,7 @@ import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itextfield.UITextField; import com.fr.design.mainframe.DesignerContext; +import com.fr.design.utils.gui.UIComponentUtils; import com.fr.file.FILE; import com.fr.file.FILEChooserPane; import com.fr.file.filter.ChooseFileFilter; @@ -46,7 +47,7 @@ public class WebCssPane extends BasicPane { northPane.add(chooseFile, FlowLayout.RIGHT); outnorth.add(northPane,BorderLayout.NORTH); UILabel infor = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CSS_Warning")); - infor.setLineWrap(); + UIComponentUtils.setLineWrap(infor); infor.setForeground(new Color(207, 42, 39)); outnorth.add(infor,BorderLayout.CENTER); this.add(outnorth, BorderLayout.NORTH); diff --git a/designer-realize/src/main/java/com/fr/design/webattr/WebJsPane.java b/designer-realize/src/main/java/com/fr/design/webattr/WebJsPane.java index 292a9d9ba..4c0505201 100644 --- a/designer-realize/src/main/java/com/fr/design/webattr/WebJsPane.java +++ b/designer-realize/src/main/java/com/fr/design/webattr/WebJsPane.java @@ -8,6 +8,7 @@ import com.fr.design.gui.ibutton.UIRadioButton; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itextfield.UITextField; import com.fr.design.mainframe.DesignerContext; +import com.fr.design.utils.gui.UIComponentUtils; import com.fr.file.FILE; import com.fr.file.FILEChooserPane; import com.fr.file.filter.ChooseFileFilter; @@ -96,7 +97,7 @@ public class WebJsPane extends BasicPane { northPane.add(chooseFile); firstnorth.add(northPane,BorderLayout.NORTH); infor1 = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_JS_WARNING1")); - infor1.setLineWrap(); + UIComponentUtils.setLineWrap(infor1); infor1.setForeground(new Color(207, 42, 39)); firstnorth.add(infor1,BorderLayout.CENTER);