diff --git a/designer-base/src/main/java/com/fr/design/actions/UpdateAction.java b/designer-base/src/main/java/com/fr/design/actions/UpdateAction.java index 5c12ff29c3..048f233373 100644 --- a/designer-base/src/main/java/com/fr/design/actions/UpdateAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/UpdateAction.java @@ -345,6 +345,17 @@ public abstract class UpdateAction extends ShortCut implements Action { return (JComponent) object; } + public JComponent createToolBarComponentByName(String componentName) { + Object object = this.getValue(componentName); + if (!(object instanceof AbstractButton)) { + UIButton button = null; + button = new UIButton(); + object = initButton(button, componentName); + } + + return (JComponent) object; + } + protected JComponent initButton(UIButton button, String name) { // 添加一个名字作为自动化测试用 button.setName(getName()); diff --git a/designer-base/src/main/java/com/fr/design/actions/help/TutorialAction.java b/designer-base/src/main/java/com/fr/design/actions/help/TutorialAction.java index 3e08b13991..51a390c82d 100644 --- a/designer-base/src/main/java/com/fr/design/actions/help/TutorialAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/help/TutorialAction.java @@ -28,7 +28,7 @@ public class TutorialAction extends AbstractDesignerSSO { @Override public String getJumpUrl() { - return CloudCenter.getInstance().acquireUrlByKind(createDocKey()); + return CloudCenter.getInstance().acquireUrlByKind(createDocKey(), "http://help.finereport.com"); } // 生成帮助文档 sitecenter key, help.zh_CN.10 diff --git a/designer-base/src/main/java/com/fr/design/border/UITitledBorder.java b/designer-base/src/main/java/com/fr/design/border/UITitledBorder.java index 3987844cf8..875ef00833 100644 --- a/designer-base/src/main/java/com/fr/design/border/UITitledBorder.java +++ b/designer-base/src/main/java/com/fr/design/border/UITitledBorder.java @@ -22,24 +22,7 @@ public class UITitledBorder extends TitledBorder { } private UITitledBorder(String title) { - super( - BorderFactory.createCompoundBorder( - BorderFactory.createEmptyBorder( - 0, - 0, - 5, - 0), - new UIRoundedBorder( - UIConstants.TITLED_BORDER_COLOR, - 1, - 10) - ), - title, - TitledBorder.LEADING, - TitledBorder.TOP, - null, - new Color(1, 159, 222) - ); + this(title, 10); } /** diff --git a/designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java b/designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java new file mode 100644 index 0000000000..c46143e1e5 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java @@ -0,0 +1,32 @@ +package com.fr.design.border; + +import com.fr.design.constants.UIConstants; + +import javax.swing.BorderFactory; +import javax.swing.border.TitledBorder; +import java.awt.Color; + +public class UITitledMatteBorder extends TitledBorder { + public static UITitledMatteBorder createTitledTopBorder(String title, Color color) { + return new UITitledMatteBorder(title, 1, 0, 0, 0, color); + } + + public static UITitledMatteBorder createTitledBorder(String title, Color color) { + return new UITitledMatteBorder(title, 1, 1, 1, 1, color); + } + + public static UITitledMatteBorder createTitledBorder(String title, int top, int left, int bottom, int right, Color color) { + return new UITitledMatteBorder(title, top, left, bottom, right, color); + } + + private UITitledMatteBorder(String title, int top, int left, int bottom, int right, Color color) { + super( + BorderFactory.createMatteBorder(top, left, bottom, right, UIConstants.TITLED_BORDER_COLOR), + title, + TitledBorder.LEADING, + TitledBorder.TOP, + null, + color + ); + } +} diff --git a/designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java b/designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java index 393f217ce7..c317d0e5a3 100644 --- a/designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java @@ -6,6 +6,9 @@ import com.fr.base.Style; import com.fr.general.IOUtils; import javax.swing.JPanel; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; @@ -40,10 +43,21 @@ public class CellStylePreviewPane extends JPanel { @Override public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; - int resolution = ScreenResolution.getScreenResolution(); - int width = getWidth(); - int height = getHeight(); + paintTransparentBackground(g2d, style); + + paintCellStyle(g2d, style); + } + + private void paintTransparentBackground(Graphics2D g2d, Style style) { + Color fontColor = style.getFRFont().getForeground(); + float g = fontColor.getRed() * 0.299F + fontColor.getGreen() * 0.587F * fontColor.getBlue() * 0.114F; + float alpha = 1.0F; + if (g < 50) { + alpha = 0.2F; + } else if (g < 160){ + alpha = 0.5F; + } float scaleWidth = 1.0F * getWidth() / transparentBackgroundWidth; float scaleHeight = 1.0F * getHeight() / transparentBackgroundHeight; @@ -54,7 +68,18 @@ public class CellStylePreviewPane extends JPanel { } else { scaleHeight = scaleWidth = maxScale; } + + Composite oldComposite = g2d.getComposite(); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); g2d.drawImage(transparentBackgroundImage, 0, 0, (int) (transparentBackgroundWidth * scaleWidth), (int) (transparentBackgroundHeight * scaleHeight), null); + g2d.setComposite(oldComposite); + } + + private void paintCellStyle(Graphics2D g2d, Style style) { + int resolution = ScreenResolution.getScreenResolution(); + + int width = getWidth(); + int height = getHeight(); if (style == Style.DEFAULT_STYLE) { // 如果是默认的style,就只写"Report"上去 diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java index b5bc39e4eb..f656105265 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java @@ -25,6 +25,7 @@ import com.fr.design.gui.icombobox.UIComboBoxEditor; import com.fr.design.gui.icombobox.UIComboBoxRenderer; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; @@ -39,7 +40,16 @@ import com.fr.stable.StringUtils; import com.fr.workspace.WorkContext; import com.fr.workspace.server.connection.DBConnectAuth; -import javax.swing.*; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.util.Collections; +import java.util.concurrent.CancellationException; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTree; +import javax.swing.SwingWorker; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.PopupMenuEvent; @@ -50,7 +60,6 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; -import java.awt.*; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; @@ -70,6 +79,9 @@ import java.util.concurrent.FutureTask; * @since 2012-7-11下午4:49:39 */ public class ChoosePane extends BasicBeanPane implements Refreshable, Previewable, Prepare4DataSourceChange { + + private static final List PENDING_CONTENT = new ArrayList<>(Collections.singletonList(Toolkit.i18nText("Fine-Design_Basic_Loading") + "...")); + private static final double COLUMN_SIZE = 24; /** @@ -91,6 +103,8 @@ public class ChoosePane extends BasicBeanPane implements Refresha private SwingWorker populateWorker; + private SwingWorker, Void> initWorker; + private PopupMenuListener popupMenuListener = new PopupMenuListener() { @Override @@ -213,10 +227,34 @@ public class ChoosePane extends BasicBeanPane implements Refresha @SuppressWarnings("unchecked") protected void initDsNameComboBox() { + if (initWorker != null && !initWorker.isDone()) { + initWorker.cancel(true); + } dsNameComboBox.setRefreshingModel(true); - FilterableComboBoxModel dsNameComboBoxModel = new FilterableComboBoxModel(getHasAuthConnections()); - dsNameComboBox.setModel(dsNameComboBoxModel); - dsNameComboBox.setRefreshingModel(false); + dsNameComboBox.setModel(new FilterableComboBoxModel(PENDING_CONTENT)); + initWorker = new SwingWorker, Void>() { + + @Override + protected List doInBackground() throws Exception { + return getHasAuthConnections(); + } + + @Override + protected void done() { + try { + FilterableComboBoxModel dsNameComboBoxModel = new FilterableComboBoxModel(get()); + String selected = dsNameComboBox.getSelectedItem(); + dsNameComboBox.setModel(dsNameComboBoxModel); + dsNameComboBox.setSelectedItem(selected); + dsNameComboBox.setRefreshingModel(false); + } catch (Exception e) { + if (!(e instanceof CancellationException)) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } + }; + initWorker.execute(); } protected void initComponentsLayout(PreviewLabel previewLabel, int labelSize) { diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java index 310558f168..3b5aebed9e 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java @@ -80,12 +80,13 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel { * 刷新ComboBox.items */ protected Iterator items() { - nameList = new ArrayList(); - ConnectionConfig mgr = ConnectionConfig.getInstance(); Iterator nameIt = mgr.getConnections().keySet().iterator(); Collection noAuthConnections = WorkContext.getCurrent().get(DBConnectAuth.class).getNoAuthConnections(); + + nameList = new ArrayList<>(); + if (noAuthConnections == null) { return nameList.iterator(); } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java index f06d1405b8..d0738e57b8 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java @@ -3,12 +3,19 @@ package com.fr.design.data.datapane.connect; import com.fr.base.BaseUtils; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; -import javax.swing.*; -import java.awt.*; +import com.fr.log.FineLoggerFactory; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.util.Iterator; +import java.util.concurrent.CancellationException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JPanel; +import javax.swing.SwingWorker; public abstract class ItemEditableComboBoxPanel extends JPanel { /** @@ -16,6 +23,8 @@ public abstract class ItemEditableComboBoxPanel extends JPanel { */ private static final long serialVersionUID = 1L; + private static final String PENDING = Toolkit.i18nText("Fine-Design_Basic_Loading") + "..."; + protected static final Object EMPTY = new Object() { public String toString() { return ""; @@ -26,6 +35,8 @@ public abstract class ItemEditableComboBoxPanel extends JPanel { protected UIButton editButton; protected UIButton refreshButton; + private SwingWorker, Void> refreshWorker; + public ItemEditableComboBoxPanel() { super(); @@ -75,6 +86,11 @@ public abstract class ItemEditableComboBoxPanel extends JPanel { * 刷新itemComboBox的内容 */ protected void refreshItems() { + + if (refreshWorker != null && !refreshWorker.isDone()) { + refreshWorker.cancel(true); + } + // 记录原来选中的Item,重新加载后需要再次选中 Object lastSelectedItem = itemComboBox.getSelectedItem(); @@ -83,18 +99,43 @@ public abstract class ItemEditableComboBoxPanel extends JPanel { // 先加EMPTY,再加items model.addElement(EMPTY); + model.addElement(PENDING); - java.util.Iterator itemIt = items(); - while(itemIt.hasNext()) { - model.addElement(itemIt.next()); + // 存在两种场景之前只考虑了填充场景 有populate会填充下 把这边的填充逻辑删了 所以没有问题 + // 如果是纯通过刷新按钮 没有populate 需要手动设置下上次选中的内容 + if (lastSelectedItem != null) { + model.setSelectedItem(lastSelectedItem); } - // 再次选中之前选中的Item - int idx = model.getIndexOf(lastSelectedItem); - if(idx < 0) { - idx = 0; - } - itemComboBox.setSelectedIndex(idx); + refreshWorker = new SwingWorker, Void>() { + @Override + protected Iterator doInBackground() throws Exception { + return items(); + } + + @Override + protected void done() { + try { + Iterator itemIt = get(); + model.removeElement(PENDING); + while(itemIt.hasNext()) { + model.addElement(itemIt.next()); + } + // 如果加载成功 但是下拉框是可见的 下拉框高度是会固定为原始高度 不会因为填充了更多下拉项而变化 + // 需要重新设置下拉框高度 但值一样时相关事件不会生效 所以先加再减下 + if (itemComboBox.isPopupVisible()) { + itemComboBox.setMaximumRowCount(itemComboBox.getMaximumRowCount() + 1); + itemComboBox.setMaximumRowCount(itemComboBox.getMaximumRowCount() - 1); + } + } catch (Exception e) { + if (!(e instanceof CancellationException)) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + } + }; + refreshWorker.execute(); } /* diff --git a/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java b/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java index 6c3323600c..b7a564713b 100644 --- a/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java +++ b/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java @@ -4,6 +4,7 @@ package com.fr.design.file; import com.fr.base.BaseUtils; import com.fr.base.GraphHelper; import com.fr.base.vcs.DesignerMode; +import com.fr.design.base.mode.DesignModeContext; import com.fr.design.constants.UIConstants; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.imenu.UIMenuItem; @@ -763,7 +764,7 @@ public class MutilTempalteTabPane extends JComponent { /** * 关闭掉一个模板之后激活新的待显示模板 */ - private void activePrevTemplateAfterClose() { + public void activePrevTemplateAfterClose() { if (openedTemplate.isEmpty()) { //新建并激活模板 DesignerContext.getDesignerFrame().addAndActivateJTemplate(); diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/JListControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/JListControlPane.java index f119c55cd3..82cba758b7 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/JListControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/JListControlPane.java @@ -23,12 +23,12 @@ import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; +import java.util.Collection; import java.awt.BorderLayout; import java.awt.Component; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; -import java.util.Collection; public abstract class JListControlPane extends JControlPane implements ListControlPaneProvider { private static final String LIST_NAME = "JControl_List"; @@ -335,7 +335,7 @@ public abstract class JListControlPane extends JControlPane implements ListContr getHelper().checkButtonEnabled(); } - private class NameableListCellRenderer extends + protected class NameableListCellRenderer extends DefaultListCellRenderer { @Override public Component getListCellRendererComponent(JList list, Object value, diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java index 648cb03f33..f7229136f5 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java @@ -387,8 +387,6 @@ public abstract class UIControlPane extends JControlPane { contentPane.setBackground(originColor); contentPane.setLayout(new BorderLayout()); titleLabel = new UILabel(title); - Font font = new Font("SimSun", Font.PLAIN, 12); - titleLabel.setFont(font); contentPane.add(titleLabel, BorderLayout.WEST); contentPane.setBorder(new EmptyBorder(5, 14, 6, 0)); diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java index 6ec5f496a6..7c40235304 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java @@ -329,7 +329,7 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li width = Math.max(width, calculateUIListMaxCellWidth(uiList.getModel(), uiList.getFontMetrics(uiList.getFont()))); } iterator = nameEdListMap.entrySet().iterator(); - width += 40; + width += 30; while (iterator.hasNext()) { Map.Entry entry = iterator.next(); ListWrapperPane wrapperPane = entry.getValue(); @@ -349,7 +349,8 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li } else { text = element.toString(); } - width = Math.max(width, fontMetrics.stringWidth(text)); + //增加 10px 的左右间隔 + width = Math.max(width, fontMetrics.stringWidth(text) + 10); } } return width; @@ -539,7 +540,8 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li label.setBackground(Color.WHITE); label.setForeground(Color.decode("#333334")); label.setFont(label.getFont().deriveFont(11F)); - label.setPreferredSize(new Dimension(224, 26)); + //预留 10px 的纵向滚动条的宽度 + label.setPreferredSize(new Dimension(214, 26)); this.nameEdList = nameEdList; this.add(label, BorderLayout.NORTH); this.add(this.nameEdList, BorderLayout.CENTER); diff --git a/designer-base/src/main/java/com/fr/design/gui/ilist/JNameEdList.java b/designer-base/src/main/java/com/fr/design/gui/ilist/JNameEdList.java index 0efa74cec7..4c530c0fcc 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ilist/JNameEdList.java +++ b/designer-base/src/main/java/com/fr/design/gui/ilist/JNameEdList.java @@ -1,25 +1,22 @@ package com.fr.design.gui.ilist; import com.fr.design.gui.NameInspector; +import com.fr.design.gui.itextfield.UITextField; import com.fr.general.GeneralUtils; import com.fr.general.NameObject; -import com.fr.base.Utils; -import com.fr.design.gui.itextfield.UITextField; - import com.fr.stable.Nameable; import com.fr.stable.StringUtils; import com.fr.stable.core.PropertyChangeAdapter; -import javax.swing.*; +import javax.swing.ListModel; import javax.swing.event.CellEditorListener; import javax.swing.event.ChangeEvent; -import java.awt.*; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Vector; +import java.awt.Component; +import java.awt.Rectangle; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; public class JNameEdList extends UIList implements CellEditorListener { private static final int ICON_WIDTH = 20; @@ -38,6 +35,8 @@ public class JNameEdList extends UIList implements CellEditorListener { */ private String oldName; + private boolean replaceEmptyName = true; + public JNameEdList(ListModel dataModel) { super(dataModel); } @@ -70,6 +69,10 @@ public class JNameEdList extends UIList implements CellEditorListener { return this.editable; } + public void setReplaceEmptyName(boolean replaceEmptyName) { + this.replaceEmptyName = replaceEmptyName; + } + public void setNameShouldNumber(boolean isNameShouldNumber) { this.isNameShouldNumber = isNameShouldNumber; } @@ -301,7 +304,7 @@ public class JNameEdList extends UIList implements CellEditorListener { ListCellEditor editor = getCellEditor(); if (editor != null && editorComp != null) { Object value = editor.getCellEditorValue(); - String name = StringUtils.isBlank(value.toString()) ? oldName : value.toString(); + String name = StringUtils.isBlank(value.toString()) && replaceEmptyName ? oldName : value.toString(); setNameAt(name, editingIndex); removeComp(); doAfterStopEditing(); 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 22f6cb246e..4a722fc50d 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java +++ b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java @@ -73,6 +73,12 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver textField.setValue(defaultValue); } + public UISpinner(double minValue, double maxValue, double dierta, double defaultValue, boolean fillNegativeNumber) { + init(minValue, maxValue, dierta); + textField.setValue(defaultValue); + textField.canFillNegativeNumber(fillNegativeNumber); + } + protected void init(double minValue, double maxValue, double dierta) { this.minValue = minValue; this.maxValue = maxValue; diff --git a/designer-base/src/main/java/com/fr/design/gui/itextfield/EditTextField.java b/designer-base/src/main/java/com/fr/design/gui/itextfield/EditTextField.java index 9ed9068273..85474ca3ce 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itextfield/EditTextField.java +++ b/designer-base/src/main/java/com/fr/design/gui/itextfield/EditTextField.java @@ -1,12 +1,11 @@ package com.fr.design.gui.itextfield; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Toolkit; - import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.PlainDocument; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Toolkit; /** diff --git a/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java b/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java index 237a5659a7..0de98c3b5f 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java @@ -487,6 +487,7 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private int ninePointBottom = -1; private static final int MIN_NINE_POINT = 0; + private static final int MIN_GAP_PARALLEL_LINES = 1; private int imgWidth; private int imgHeight; @@ -757,8 +758,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private void onNinePointTopChanged(int value) { if (value < MIN_NINE_POINT) { value = MIN_NINE_POINT; - } else if (value >= imgHeight - ninePointBottom) { - value = imgHeight - ninePointBottom - MIN_NINE_POINT; + } else if (value >= imgHeight - ninePointBottom - MIN_GAP_PARALLEL_LINES) { + value = imgHeight - ninePointBottom - MIN_GAP_PARALLEL_LINES; } this.ninePointTop = value; repaint(); @@ -767,8 +768,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private void onNinePointBottomChanged(int value) { if (value < MIN_NINE_POINT) { value = MIN_NINE_POINT; - } else if (value >= imgHeight - ninePointTop) { - value = imgHeight - ninePointTop - MIN_NINE_POINT; + } else if (value >= imgHeight - ninePointTop - MIN_GAP_PARALLEL_LINES) { + value = imgHeight - ninePointTop - MIN_GAP_PARALLEL_LINES; } this.ninePointBottom = value; repaint(); @@ -777,8 +778,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private void onNinePointLeftChanged(int value) { if (value < MIN_NINE_POINT) { value = MIN_NINE_POINT; - } else if (value >= imgWidth - ninePointRight) { - value = imgWidth - ninePointRight - MIN_NINE_POINT; + } else if (value >= imgWidth - ninePointRight - MIN_GAP_PARALLEL_LINES) { + value = imgWidth - ninePointRight - MIN_GAP_PARALLEL_LINES; } this.ninePointLeft = value; repaint(); @@ -787,8 +788,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private void onNinePointRightChanged(int value) { if (value < MIN_NINE_POINT) { value = MIN_NINE_POINT; - } else if (value >= imgWidth - ninePointLeft) { - value = imgWidth - ninePointLeft - MIN_NINE_POINT; + } else if (value >= imgWidth - ninePointLeft - MIN_GAP_PARALLEL_LINES) { + value = imgWidth - ninePointLeft - MIN_GAP_PARALLEL_LINES; } this.ninePointRight = value; repaint(); diff --git a/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java b/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java index f3367206f5..460e838c51 100644 --- a/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java +++ b/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java @@ -2,6 +2,7 @@ package com.fr.design.javascript; import com.fr.base.BaseFormula; import com.fr.base.Parameter; +import com.fr.base.extension.FileExtension; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.DialogActionAdapter; @@ -417,6 +418,9 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane { + + @Override + @Nullable + Set getNoAuthDatasetNames(DSColumn dsColumn, Set authDatasetNames) { + if (!authDatasetNames.contains(dsColumn.getDSName())) { + return new HashSet<>(Arrays.asList(dsColumn.getDSName())); + } + return null; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/authority/ElementAuthorityChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/authority/ElementAuthorityChecker.java new file mode 100644 index 0000000000..67d0f1da36 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/authority/ElementAuthorityChecker.java @@ -0,0 +1,45 @@ +package com.fr.design.mainframe.authority; + +import org.jetbrains.annotations.Nullable; +import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; + +import java.lang.reflect.Type; +import java.util.Set; + + +public abstract class ElementAuthorityChecker { + + + /** + * @Description 获取越权的数据连接 + * @param: t 待检查的对象 + * @param: authConnectionNames 有权限的数据连接名 + * @return 如果有返回名称,没有返回null + */ + @Nullable + Set getNoAuthConnectionNames(T t, Set authConnectionNames) { + return null; + } + + + /** + * @Description 获取越权的服务器数据集 + * @param: t 待检查的对象 + * @param: authDatasetNames 有权限的服务器数据集名 + * @return 如果有返回名称,没有返回null + */ + @Nullable + Set getNoAuthDatasetNames(T t, Set authDatasetNames) { + return null; + } + + /** + * @Description 要检查对象的className + * @return className + */ + String getCheckClassName() { + ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) this.getClass().getGenericSuperclass(); + Type type = parameterizedType.getActualTypeArguments()[0]; + return type.getTypeName(); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/authority/FormulaAuthorityChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/authority/FormulaAuthorityChecker.java new file mode 100644 index 0000000000..d108c18d41 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/authority/FormulaAuthorityChecker.java @@ -0,0 +1,27 @@ +package com.fr.design.mainframe.authority; + +import com.fr.base.Formula; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class FormulaAuthorityChecker extends ElementAuthorityChecker { + private static final Pattern FORMULA_PATTERN = Pattern.compile("^=SQL\\(\"(.+?)\","); + + @Override + @Nullable + public Set getNoAuthConnectionNames(Formula formula, Set authConnectionNames) { + String content = formula.getContent(); + Matcher matcher = FORMULA_PATTERN.matcher(content); + if (matcher.find()) { + if (!authConnectionNames.contains(matcher.group(1))) { + return new HashSet<>(Arrays.asList(matcher.group(1))); + } + } + return null; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/authority/JTemplateAuthorityChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/authority/JTemplateAuthorityChecker.java new file mode 100644 index 0000000000..f8b2c8ce6b --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/authority/JTemplateAuthorityChecker.java @@ -0,0 +1,184 @@ +package com.fr.design.mainframe.authority; + + +import com.fr.design.dialog.FineJOptionPane; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mod.ModClassFilter; +import com.fr.invoke.ClassHelper; + +import com.fr.log.FineLoggerFactory; +import com.fr.rpc.ExceptionHandler; +import com.fr.rpc.RPCInvokerExceptionInfo; +import com.fr.stable.Filter; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.authority.user.UserAuthority; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + + +import static javax.swing.JOptionPane.WARNING_MESSAGE; + + +public class JTemplateAuthorityChecker { + JTemplate jTemplate; + Set authConnectionNames; + Set authDatasetNames; + Map checkerMap = new HashMap<>(); + Set authFailConnectionNames = new HashSet<>(); + Set authFailDatasetNames = new HashSet<>(); + + + public JTemplateAuthorityChecker(JTemplate jTemplate) { + long s = System.currentTimeMillis(); + this.jTemplate = jTemplate; + this.initAuthNames(); + this.initChecker(); + FineLoggerFactory.getLogger().info("JTemplateAuthorityChecker init time consume:" + (System.currentTimeMillis() - s)); + } + + private void initAuthNames() { + UserAuthority templateAuthority = WorkContext.getCurrent().get(UserAuthority.class); + Map> authNamesMap = templateAuthority.getAuthServerDataSetAndConnectionNames(); + if (authNamesMap != null) { + //有权限的数据连接名称 + authConnectionNames = authNamesMap.get(UserAuthority.AUTH_CONNECTION_NAMES); + //有权限的数据集名称(模板数据集和服务器数据集) + authDatasetNames = authNamesMap.get(UserAuthority.AUTH_SERVER_DATASET_NAMES); + Iterator iterator = jTemplate.getTarget().getTableDataNameIterator(); + while (iterator.hasNext()) { + String datasetName = iterator.next(); + authDatasetNames.add(datasetName); + } + } + } + + private void initChecker() { + registerChecker(new NameDatabaseConnectionAuthorityChecker()); + registerChecker(new DSColumnAuthorityChecker()); + registerChecker(new FormulaAuthorityChecker()); + registerChecker(new NameTableDataAuthorityChecker()); + } + + private void registerChecker(ElementAuthorityChecker checker) { + checkerMap.put(checker.getCheckClassName(), checker); + } + + + public boolean isAuthority() { + long s = System.currentTimeMillis(); + //遍历模板对象,根据checkerMap.keySet()把感兴趣的对象找出来 + Map> targetObjects = ClassHelper.searchObject(jTemplate.getTarget(), checkerMap.keySet(), ClassFilter.getInstance()); + + //找到对应的checker,对对象进行检查 + for (String name : targetObjects.keySet()) { + ElementAuthorityChecker checker = checkerMap.get(name); + for (Object object : targetObjects.get(name)) { + if (authConnectionNames != null) { + Set noAuthName = checker.getNoAuthConnectionNames(object, authConnectionNames); + if (noAuthName != null) { + authFailConnectionNames.addAll(noAuthName); + } + } + if (authDatasetNames != null) { + Set noAuthName = checker.getNoAuthDatasetNames(object, authDatasetNames); + if (noAuthName != null) { + authFailDatasetNames.addAll(noAuthName); + } + } + } + } + + FineLoggerFactory.getLogger().info("JTemplateAuthorityChecker check time consume:" + (System.currentTimeMillis() - s)); + return authFailConnectionNames.size() == 0 && authFailDatasetNames.size() == 0; + } + + public void showAuthorityFailPromptDialog() { + StringBuffer stringBuffer = new StringBuffer(); + stringBuffer.append(Toolkit.i18nText("Fine-Design-Basic_Save_Failure")); + stringBuffer.append("\n"); + stringBuffer.append(getPromptInfo(authFailDatasetNames, + Toolkit.i18nText("Fine-Design_Template_Authority_Check_Server_Dataset_Authority"))); + stringBuffer.append(getPromptInfo(authFailConnectionNames, + Toolkit.i18nText("Fine-Design_Template_Authority_Check_Data_Connection_Authority"))); + FineJOptionPane.showMessageDialog( + DesignerContext.getDesignerFrame(), + stringBuffer.toString(), + Toolkit.i18nText("Fine-Design_Basic_Alert"), + WARNING_MESSAGE); + } + + private String getPromptInfo(Set authFailNames, String message) { + StringBuffer stringBuffer = new StringBuffer(); + if (authFailNames.size() > 0) { + stringBuffer.append(Toolkit.i18nText("Fine-Design_Template_Authority_Check_Current_Operator_Miss")); + stringBuffer.append(authFailNames.size()); + stringBuffer.append(Toolkit.i18nText("Fine-Design_Report_Ge")); + stringBuffer.append(message); + stringBuffer.append("\n"); + stringBuffer.append(getNoAuthNameSequence(authFailNames)); + } + return stringBuffer.toString(); + } + + private String getNoAuthNameSequence(Set names) { + StringBuffer stringBuffer = new StringBuffer(); + int showMaxCount = 3; + int count = 0; + for (String name : names) { + if (count == showMaxCount) { + stringBuffer.append(Toolkit.i18nText("Fine-Design_Template_Authority_Check_Etc")); + break; + } + stringBuffer.append(name); + if (count != names.size() - 1 && count != showMaxCount - 1) { + stringBuffer.append(";"); + } + count++; + } + stringBuffer.append("\n"); + return stringBuffer.toString(); + } + + static class ClassFilter implements Filter { + + private static final Set FILTER_SET = new HashSet<>(); + private static final Set START_WITH_SET = new HashSet<>(); + private static final Filter INSTANCE = new ModClassFilter(); + + public static Filter getInstance() { + return INSTANCE; + } + + static { + FILTER_SET.add("java.awt.image.BufferedImage"); + FILTER_SET.add("sun.awt.AppContext"); + FILTER_SET.add("com.fr.poly.creator.ECBlockCreator"); + FILTER_SET.add("io.netty.channel.nio.SelectedSelectionKeySet"); + FILTER_SET.add("com.fr.form.ui.ElementCaseImage"); + FILTER_SET.add("this$0"); + START_WITH_SET.add("com.fr.design"); + } + + @Override + public boolean accept(String s) { + if (FILTER_SET.contains(s)) { + return true; + } + for (String start : START_WITH_SET) { + if (s.startsWith(start)) { + return true; + } + } + return false; + } + } +} + diff --git a/designer-base/src/main/java/com/fr/design/mainframe/authority/NameDatabaseConnectionAuthorityChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/authority/NameDatabaseConnectionAuthorityChecker.java new file mode 100644 index 0000000000..96bc0b8c5d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/authority/NameDatabaseConnectionAuthorityChecker.java @@ -0,0 +1,22 @@ +package com.fr.design.mainframe.authority; + +import com.fr.data.impl.NameDatabaseConnection; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +public class NameDatabaseConnectionAuthorityChecker extends ElementAuthorityChecker { + @Override + @Nullable + Set getNoAuthConnectionNames(NameDatabaseConnection nameDatabaseConnection, Set authConnectionNames) { + String name = nameDatabaseConnection.getName(); + if (!authConnectionNames.contains(name)) { + return new HashSet<>(Arrays.asList(name)); + } + return null; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/authority/NameTableDataAuthorityChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/authority/NameTableDataAuthorityChecker.java new file mode 100644 index 0000000000..13e7300856 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/authority/NameTableDataAuthorityChecker.java @@ -0,0 +1,19 @@ +package com.fr.design.mainframe.authority; + +import com.fr.data.impl.NameTableData; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class NameTableDataAuthorityChecker extends ElementAuthorityChecker { + @Override + @Nullable + Set getNoAuthDatasetNames(NameTableData nameTableData, Set authDatasetNames) { + if (!authDatasetNames.contains(nameTableData.getName())) { + return new HashSet<>(Arrays.asList(nameTableData.getName())); + } + return null; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java index f34f8a27f0..798bb73c59 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java @@ -36,46 +36,56 @@ public class FormThemeProfilePane extends TemplateThemeProfilePane { } @Override - protected JPanel createCustomEditorsPane() { - JPanel container = super.createCustomEditorsPane(); - formBodyStyleSettingPane = new FormBodyStyleEditPane(); - addCustomEditorPane(i18nText("Fine-Design_Predefined_Template_Background"), formBodyStyleSettingPane); - - addCustomEditorPane(i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane()); - addCustomEditorPane(i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane()); - - - componentStyleSettingPane = new ComponentStyleEditPane(); - addCustomEditorPane(i18nText("Fine-Design_Predefined_Component_Style"), componentStyleSettingPane); - return container; + public TemplateThemeEditorPane createThemeEditorPane() { + return new FormThemeEditorPane(config); } @Override - protected JPanel createChartStyleSettingPane() { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - chartStyleSettingPane = new ChartStyleFormEditPane(); - container.add(chartStyleSettingPane); - return container; + public String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Form_Theme_Profile_Dialog_Title"); } - @Override - public void populateBean4CustomEditors(FormTheme theme) { - super.populateBean4CustomEditors(theme); - formBodyStyleSettingPane.populateBean(theme.getBodyStyle()); - componentStyleSettingPane.populateBean(theme.getComponentStyle()); - } + private static class FormThemeEditorPane extends TemplateThemeEditorPane { - @Override - public void updateBean(FormTheme theme) { - ThemedFormBodyStyle formBodyStyle = formBodyStyleSettingPane.updateBean(); - theme.setBodyStyle(formBodyStyle); + private final FormBodyStyleEditPane formBodyStyleSettingPane; + private final ComponentStyleEditPane componentStyleSettingPane; - ThemedComponentStyle componentStyle = componentStyleSettingPane.updateBean(); - theme.setComponentStyle(componentStyle); - } + public FormThemeEditorPane(TemplateThemeConfig config) { + super(config); + formBodyStyleSettingPane = new FormBodyStyleEditPane(); + addCustomEditorPane(i18nText("Fine-Design_Predefined_Template_Background"), formBodyStyleSettingPane); - @Override - public String title4PopupWindow() { - return Toolkit.i18nText("Fine-Design_Basic_Form_Theme_Profile_Dialog_Title"); + addCustomEditorPane(i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane()); + addCustomEditorPane(i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane()); + + + componentStyleSettingPane = new ComponentStyleEditPane(); + addCustomEditorPane(i18nText("Fine-Design_Predefined_Component_Style"), componentStyleSettingPane); + } + + @Override + protected JPanel createChartStyleSettingPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + chartStyleSettingPane = new ChartStyleFormEditPane(); + container.add(chartStyleSettingPane); + return container; + } + + @Override + protected void populateBean4CustomEditors(FormTheme theme) { + super.populateBean4CustomEditors(theme); + formBodyStyleSettingPane.populateBean(theme.getBodyStyle()); + componentStyleSettingPane.populateBean(theme.getComponentStyle()); + } + + @Override + protected void updateBean4CustomEditors(FormTheme theme) { + super.updateBean4CustomEditors(theme); + ThemedFormBodyStyle formBodyStyle = formBodyStyleSettingPane.updateBean(); + theme.setBodyStyle(formBodyStyle); + + ThemedComponentStyle componentStyle = componentStyleSettingPane.updateBean(); + theme.setComponentStyle(componentStyle); + } } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java index 1158a8eb5d..f0f25f677f 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java @@ -25,28 +25,37 @@ public class ReportThemeProfilePane extends TemplateThemeProfilePane createThemeEditorPane() { + return new ReportThemeEditorPane(config); } @Override public String title4PopupWindow() { return Toolkit.i18nText("Fine-Design_Basic_Report_Theme_Profile_Dialog_Title"); } + + private static class ReportThemeEditorPane extends TemplateThemeEditorPane { + + private final ReportBodyStyleEditPane reportBodyStyleSettingPane; + + public ReportThemeEditorPane(TemplateThemeConfig config) { + super(config); + this.reportBodyStyleSettingPane = new ReportBodyStyleEditPane(); + addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Template_Background"), reportBodyStyleSettingPane); + addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane()); + addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane()); + } + + @Override + public void populateBean4CustomEditors(ReportTheme theme) { + super.populateBean4CustomEditors(theme); + reportBodyStyleSettingPane.populateBean(theme.getBodyStyle()); + } + + @Override + public void updateBean4CustomEditors(ReportTheme theme) { + super.updateBean4CustomEditors(theme); + theme.setBodyStyle(this.reportBodyStyleSettingPane.updateBean()); + } + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java new file mode 100644 index 0000000000..a5301e9565 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java @@ -0,0 +1,315 @@ +package com.fr.design.mainframe.theme; + +import com.fr.base.theme.FineColorFlushUtils; +import com.fr.base.theme.FineColorManager; +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; +import com.fr.base.theme.settings.ThemedCellStyleList; +import com.fr.base.theme.settings.ThemedColorScheme; +import com.fr.design.designer.IntervalConstants; +import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; +import com.fr.design.gui.frpane.AttributeChangeListener; +import com.fr.design.gui.frpane.UITabbedPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.theme.edit.CellStyleListEditPane; +import com.fr.design.mainframe.theme.edit.ChartStyleEditPane; +import com.fr.design.mainframe.theme.edit.ui.ColorListExtendedPane; +import com.fr.design.mainframe.theme.edit.ui.ColorListPane; +import com.fr.design.mainframe.theme.edit.ui.LabelUtils; +import com.fr.design.mainframe.theme.ui.AutoCheckTextField; +import com.fr.design.mainframe.theme.ui.AutoCheckThemeNameTextField; +import com.fr.design.mainframe.theme.ui.BorderUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.util.List; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/8/13 + */ +public abstract class TemplateThemeEditorPane extends JPanel { + public static final int LEFT_TITLE_PANE_HEIGHT = 539; + + public static final int RIGHT_PANE_WIDTH = 362; + public static final int RIGHT_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT; + + protected AutoCheckThemeNameTextField nameTextField; + private UILabel nameErrorLabel; + protected ColorListPane colorListPane; + private ColorListExtendedPane colorListExtendedPane; + protected CellStyleListEditPane cellStyleSettingPane; + protected ChartStyleEditPane chartStyleSettingPane; + + protected boolean isPopulating = false; + protected UITabbedPane uiTabbedPane; + + private final TemplateThemeConfig config; + + private boolean refreshingThemedColor = false; + private T theme; + + private AttributeChangeListener changeListener; + private AutoCheckTextField.CheckListener themeNameCheckListener; + + public TemplateThemeEditorPane(TemplateThemeConfig config) { + super(); + this.config = config; + theme = config.createNewTheme(); + initializePane(); + } + + private void initializePane() { + setLayout(new BorderLayout(0, 0)); + setPreferredSize(new Dimension(RIGHT_PANE_WIDTH, RIGHT_PANE_HEIGHT)); + JPanel nameEditPane = createNameEditPane(); + add(nameEditPane, BorderLayout.NORTH); + + JPanel settingPane = new JPanel(new BorderLayout(0, IntervalConstants.INTERVAL_L1)); + settingPane.add(createColorSchemeEditPane(), BorderLayout.NORTH); + settingPane.add(createCustomEditorsPane(), BorderLayout.CENTER); + + add(settingPane, BorderLayout.CENTER); + } + + private JPanel createNameEditPane() { + nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED); + nameErrorLabel.setVisible(false); + + nameTextField = new AutoCheckThemeNameTextField<>(); + nameTextField.setThemeConfig(config); + nameTextField.setEditable(false); + nameTextField.setEnabled(false); + nameTextField.setPreferredSize(new Dimension(165, 20)); + nameTextField.setNameCheckListener(new AutoCheckTextField.CheckListener() { + @Override + public void onChecked(String error, boolean valid) { + nameErrorLabel.setVisible(StringUtils.isNotEmpty(error)); + nameErrorLabel.setText(error); + + themeNameCheckListener.onChecked(error, valid); + } + }); + + double p = TableLayout.PREFERRED; + + JPanel container = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{ + new Component[] { LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Name")), nameTextField }, + new Component[] { null, nameErrorLabel }, + }, new double[] { 20, 20}, new double[] { p, 165}, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_W0); + + container.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + return container; + } + + private JPanel createColorSchemeEditPane() { + colorListPane = new ColorListPane(); + colorListExtendedPane = new ColorListExtendedPane(); + + colorListExtendedPane.setBackground(null); + colorListExtendedPane.setOpaque(false); + JPanel extendedBackgroundContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); + extendedBackgroundContainer.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + extendedBackgroundContainer.setBackground(Color.WHITE); + extendedBackgroundContainer.add(colorListExtendedPane, BorderLayout.WEST); + JPanel extendedContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); + extendedContainer.add(extendedBackgroundContainer, BorderLayout.WEST); + + double p = TableLayout.PREFERRED; + double[] rowSize = new double[]{p, p, p}; + double[] columnSize = {p, p}; + + JPanel colorListContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + colorListContainerPane.add(colorListPane, BorderLayout.WEST); + + JPanel previewLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + previewLabelPane.add(LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Preview_Label")), BorderLayout.NORTH); + + UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Tip"), new Color(153, 153, 153)); + tipLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); + + JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ + {LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Label")), colorListContainerPane}, + {null, tipLabel}, + {previewLabelPane, extendedContainer}, + }, + rowSize, columnSize, 18, 7); + content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + JPanel borderContainer = new JPanel(new BorderLayout()); + borderContainer.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Title"))); + borderContainer.add(content); + + JPanel container = new JPanel(new BorderLayout()); + container.add(borderContainer, BorderLayout.CENTER); + + colorListPane.addColorChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + if (refreshingThemedColor) { + return; + } + List colors = colorListPane.update(); + refreshingThemedColor = true; + onColorSchemeChanged(colors); + refreshingThemedColor = false; + + fireAttributeChange(); + } + }); + + return container; + } + private void onColorSchemeChanged(List colors) { + colorListExtendedPane.populate(colors); + FineColorManager.FineColorReplaceByColorScheme replaceByColorScheme = new FineColorManager.FineColorReplaceByColorScheme(colors); + T theme = updateBean(); + FineColorFlushUtils.replaceCacheObject(theme, replaceByColorScheme); + FineColorManager.traverse(theme, replaceByColorScheme); + populateBean4CustomEditors(theme); + //图表渐变色 + chartStyleSettingPane.populateGradientBar(colors); + this.repaint(); + } + + protected JPanel createCustomEditorsPane() { + JPanel container = new JPanel(new BorderLayout()); + container.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Custom_Settings_Title"))); + + uiTabbedPane = new UITabbedPane(); + uiTabbedPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 1)); + container.add(uiTabbedPane, BorderLayout.CENTER); + + return container; + } + + public void addCustomEditorPane(String title, final Component component) { + AbstractAttrNoScrollPane settingPane = new NoBorderAbstractAttrNoScrollPane() { + @Override + protected JPanel createContentPane() { + JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + contentPane.add(component, BorderLayout.CENTER); + return contentPane; + } + }; + settingPane.addAttributeChangeListener(new AttributeChangeListener() { + @Override + public void attributeChange() { + fireAttributeChange(); + } + }); + uiTabbedPane.addTab(title, settingPane); + } + protected JPanel createCellStyleSettingPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + cellStyleSettingPane = new CellStyleListEditPane(); + cellStyleSettingPane.registerAttrChangeListener(new AttributeChangeListener() { + @Override + public void attributeChange() { + fireAttributeChange(); + } + }); + container.add(cellStyleSettingPane); + return container; + } + protected JPanel createChartStyleSettingPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + chartStyleSettingPane = new ChartStyleEditPane(); + container.add(chartStyleSettingPane); + return container; + } + + public void populateBean(T theme) { + this.theme = theme; + isPopulating = true; + + String name = theme.getName(); + setThemeNameEditable(StringUtils.isEmpty(name)); + + nameTextField.setText(name); + + colorListPane.populate(theme.getColorScheme().getColors()); + colorListExtendedPane.populate(colorListPane.update()); + + populateBean4CustomEditors(theme); + isPopulating = false; + } + + protected void populateBean4CustomEditors(T theme) { + cellStyleSettingPane.populateBean(theme.getCellStyleList()); + chartStyleSettingPane.populateBean(theme.getChartStyle()); + } + + public T updateBean() { + if (theme == null) { + theme = config.createNewTheme(); + } + + theme.setName(this.nameTextField.getText()); + + ThemedColorScheme colorScheme = theme.getColorScheme(); + colorScheme.setColors(this.colorListPane.update()); + theme.setColorScheme(colorScheme); + + updateBean4CustomEditors(theme); + + return theme; + } + + protected void updateBean4CustomEditors(T theme) { + ThemedCellStyleList cellStyleConfig = this.cellStyleSettingPane.updateBean(); + theme.setCellStyleList(cellStyleConfig); + + theme.setChartStyle(this.chartStyleSettingPane.updateBean()); + } + + public void setThemeNameEditable(boolean editable) { + nameTextField.setEditable(editable); + nameTextField.setEnabled(editable); + } + + public boolean checkNameValid() { + return nameTextField.checkValid(); + } + + public List getCurrentColorScheme() { + return colorListPane.update(); + } + + private void fireAttributeChange() { + if (!isPopulating && !refreshingThemedColor && changeListener != null) { + changeListener.attributeChange(); + } + } + + public void addAttributeChangeListener(AttributeChangeListener changeListener) { + this.changeListener = changeListener; + } + public void addThemeNameCheckListener(AutoCheckTextField.CheckListener checkListener) { + this.themeNameCheckListener = checkListener; + } + + private static abstract class NoBorderAbstractAttrNoScrollPane extends AbstractAttrNoScrollPane { + @Override + protected void initContentPane() { + super.initContentPane(); + if (leftContentPane != null) { + // 修正 AbstractAttrNoScrollPane 的默认行为 + leftContentPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + } + } + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java index fca01386c4..768eb37242 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java @@ -32,7 +32,7 @@ public class TemplateThemeListPane extends BasicPane { public static final int BLOCK_GAP = IntervalConstants.INTERVAL_L1; public static final int CONTENT_WIDTH = TemplateThemeBlock.CONTENT_WIDTH * BLOCK_COUNT_ROW_LINE + BLOCK_GAP * (BLOCK_COUNT_ROW_LINE - 1) + 10; public static final int BLOCK_ROWS_PER_PAGE = 3; - public static final int CONTENT_HEIGHT = TemplateThemeBlock.CONTENT_HEIGHT * BLOCK_ROWS_PER_PAGE + BLOCK_GAP * (BLOCK_ROWS_PER_PAGE + 1); + public static final int CONTENT_HEIGHT = Math.min(527, TemplateThemeBlock.CONTENT_HEIGHT * BLOCK_ROWS_PER_PAGE + BLOCK_GAP * (BLOCK_ROWS_PER_PAGE + 1)); public static final int ASYNC_FETCH_THEME_THREAD_COUNT = 10; private final AsyncThemeFetcher asyncThemeFetcher; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java index 19885763cc..c302cf1ad8 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java @@ -48,9 +48,6 @@ public abstract class TemplateThemePreviewPane extends int height = getHeight(); try { - // 使用TYPE_INT_RGB和new Color(255, 255, 255, 1)设置有透明背景buffer image, - // 使得创建出来的透明像素是(255, 255, 255, 1),而不是(0, 0, 0, 0) - // 这样不支持透明通道缩略图的旧设计器打开新设计器创建的模版时,就不会创建出拥有黑色背景的缩略图 image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = image.createGraphics(); // 创建一个支持透明背景的buffer image @@ -58,8 +55,6 @@ public abstract class TemplateThemePreviewPane extends g2d.dispose(); g2d = image.createGraphics(); - g2d.fillRect(0, 0, width, height); - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.clipRect(0, 0, width, height); @@ -80,6 +75,9 @@ public abstract class TemplateThemePreviewPane extends @Override public void paintComponent(Graphics g) { g.clearRect(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT); + // 添加个默认白色,否则因为上面的clearRect导致无背景时会出现黑色 + g.setColor(Color.WHITE); + g.fillRect(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT); paintBackground((Graphics2D) g); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java index d5103f8246..f3187acaab 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java @@ -1,58 +1,39 @@ package com.fr.design.mainframe.theme; -import com.fr.base.theme.FineColorFlushUtils; -import com.fr.base.theme.FineColorManager; import com.fr.base.theme.TemplateTheme; import com.fr.base.theme.TemplateThemeConfig; import com.fr.base.theme.settings.ThemeThumbnail; -import com.fr.base.theme.settings.ThemedCellStyleList; -import com.fr.base.theme.settings.ThemedColorScheme; -import com.fr.design.designer.IntervalConstants; +import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.FineJOptionPane; -import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; import com.fr.design.gui.frpane.AttributeChangeListener; -import com.fr.design.gui.frpane.UITabbedPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.itextfield.UITextField; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.layout.TableLayout; -import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.theme.dialog.TemplateThemeProfileDialog; -import com.fr.design.mainframe.theme.edit.CellStyleListEditPane; -import com.fr.design.mainframe.theme.edit.ChartStyleEditPane; -import com.fr.design.mainframe.theme.edit.ui.ColorListExtendedPane; -import com.fr.design.mainframe.theme.edit.ui.ColorListPane; import com.fr.design.mainframe.theme.edit.ui.LabelUtils; +import com.fr.design.mainframe.theme.ui.AutoCheckTextField; +import com.fr.design.mainframe.theme.ui.AutoCheckThemeNameTextField; import com.fr.design.mainframe.theme.ui.BorderUtils; +import com.fr.design.mainframe.toast.DesignerToastMsgUtil; import com.fr.design.utils.gui.GUICoreUtils; -import com.fr.general.Inter; import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; import com.fr.transaction.CallBackAdaptor; + import javax.swing.BorderFactory; -import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Component; import java.awt.Dimension; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.FocusAdapter; -import java.awt.event.FocusEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.util.List; import static com.fr.design.i18n.Toolkit.i18nText; @@ -61,71 +42,35 @@ import static com.fr.design.i18n.Toolkit.i18nText; * @version 1.0 * Created by Starryi on 2021/8/13 */ -public abstract class TemplateThemeProfilePane extends AbstractAttrNoScrollPane { +public abstract class TemplateThemeProfilePane extends BasicPane { public static final int TITLE_BORDER_FONT = 12; public static final int LEFT_TITLE_PANE_WIDTH = 627; public static final int LEFT_TITLE_PANE_HEIGHT = 539; public static final int PREVIEW_PANE_WIDTH = LEFT_TITLE_PANE_WIDTH - 10; public static final int PREVIEW_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT - TITLE_BORDER_FONT - 16; - public static final int RIGHT_PANE_WIDTH = 362; - public static final int RIGHT_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT; - public static final int COLOR_SCHEME_TITLE_PANE_WIDTH = 298; - public static final int COLOR_SCHEME_TITLE_PANE_HEIGHT = 174 + TITLE_BORDER_FONT / 2; - protected TemplateThemePreviewPane themePreviewPane; - - protected UITextField nameTextField; - private UILabel nameErrorLabel; - protected ColorListPane colorListPane; - private ColorListExtendedPane colorListExtendedPane; - protected CellStyleListEditPane cellStyleSettingPane; - protected ChartStyleEditPane chartStyleSettingPane; + protected TemplateThemeEditorPane themeEditorPane; protected boolean isPopulating = false; - protected UITabbedPane uiTabbedPane; + protected boolean isMutable = false; - private final TemplateThemeConfig config; + protected final TemplateThemeConfig config; private UIButton saveButton = new UIButton(); private UIButton saveAsButton = new UIButton(); - private boolean refreshingThemedColor = false; - - private boolean currentIsNewTheme; - private T theme; - public TemplateThemeProfilePane(TemplateThemeConfig config) { + super(); this.config = config; - theme = config.createNewTheme(); - } - @Override - protected JPanel createContentPane() { - JPanel container = new JPanel(new BorderLayout(5, 0)); - container.add(createLeftPane(), BorderLayout.CENTER); - container.add(createRightPane(), BorderLayout.EAST); - addAttributeChangeListener(new AttributeChangeListener() { - @Override - public void attributeChange() { - if (!isPopulating) { - valueChangeAction(); - } - } - }); - return container; - } - - @Override - protected void initContentPane() { - super.initContentPane(); - if (leftContentPane != null) { - // 修正 AbstractAttrNoScrollPane 的默认行为 - leftContentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 6)); - } + initializePane(); } - public void valueChangeAction() { - themePreviewPane.refresh(updateBean()); + private void initializePane() { + setLayout(new BorderLayout(5, 0)); + setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 6)); + add(createLeftPane(), BorderLayout.CENTER); + add(createRightPane(), BorderLayout.EAST); } @Override @@ -149,221 +94,55 @@ public abstract class TemplateThemeProfilePane extends return titleContainer; } private JPanel createRightPane() { - JPanel container = new JPanel(new BorderLayout(0, 0)); - container.setPreferredSize(new Dimension(RIGHT_PANE_WIDTH, RIGHT_PANE_HEIGHT)); - JPanel nameEditPane = createNameEditPane(); - container.add(nameEditPane, BorderLayout.NORTH); - - JPanel settingPane = new JPanel(new BorderLayout(0, IntervalConstants.INTERVAL_L1)); - container.add(settingPane, BorderLayout.CENTER); - settingPane.add(createColorSchemeEditPane(), BorderLayout.NORTH); - settingPane.add(createCustomEditorsPane(), BorderLayout.CENTER); - - uiTabbedPane.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - valueChangeAction(); - } - }); - - return container; - } - - private JPanel createNameEditPane() { - nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED); - nameErrorLabel.setVisible(false); - - nameTextField = new UITextField(); - nameTextField.setEnabled(false); - nameTextField.setPreferredSize(new Dimension(165, 20)); - nameTextField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, false, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); - } - } - - @Override - public void removeUpdate(DocumentEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, false, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); - } - } - - @Override - public void changedUpdate(DocumentEvent e) { - - } - }); - nameTextField.addFocusListener(new FocusAdapter() { + themeEditorPane = createThemeEditorPane(); + themeEditorPane.addAttributeChangeListener(new AttributeChangeListener() { @Override - public void focusGained(FocusEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, false, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); - } - } - - @Override - public void focusLost(FocusEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, true, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); + public void attributeChange() { + if (isPopulating) { + return; } + themePreviewPane.refresh(updateBean()); + saveButton.setEnabled(themeEditorPane.checkNameValid() && isMutable); } }); - - double p = TableLayout.PREFERRED; - - JPanel container = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{ - new Component[] { LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Name")), nameTextField }, - new Component[] { null, nameErrorLabel }, - }, new double[] { 20, 20}, new double[] { p, 165}, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_W0); - - container.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); - return container; - } - private JPanel createColorSchemeEditPane() { - colorListPane = new ColorListPane(); - colorListExtendedPane = new ColorListExtendedPane(); - - JPanel extendedContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); - colorListExtendedPane.setBackground(null); - colorListExtendedPane.setOpaque(false); - extendedContainer.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - extendedContainer.setBackground(Color.WHITE); - extendedContainer.add(colorListExtendedPane); - - double p = TableLayout.PREFERRED; - double[] rowSize = new double[]{p, p, p}; - double[] columnSize = {p, p}; - - JPanel colorListContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - colorListContainerPane.add(colorListPane, BorderLayout.WEST); - - JPanel previewLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - previewLabelPane.add(LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Preview_Label")), BorderLayout.NORTH); - - UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Tip"), new Color(153, 153, 153)); - tipLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); - - JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ - {LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Label")), colorListContainerPane}, - {null, tipLabel}, - {previewLabelPane, extendedContainer}, - }, - rowSize, columnSize, 18, 7); - content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - - JPanel borderContainer = new JPanel(new BorderLayout()); - borderContainer.setPreferredSize(new Dimension(COLOR_SCHEME_TITLE_PANE_WIDTH, COLOR_SCHEME_TITLE_PANE_HEIGHT)); - borderContainer.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Title"))); - borderContainer.add(content); - - JPanel container = new JPanel(new BorderLayout()); - container.add(borderContainer, BorderLayout.WEST); - - colorListPane.addColorChangeListener(new ChangeListener() { + themeEditorPane.addThemeNameCheckListener(new AutoCheckTextField.CheckListener() { @Override - public void stateChanged(ChangeEvent e) { - if (refreshingThemedColor) { + public void onChecked(String error, boolean valid) { + if (isPopulating) { return; } - List colors = colorListPane.update(); - refreshingThemedColor = true; - onColorSchemeChanged(colors); - refreshingThemedColor = false; + saveButton.setEnabled(valid && isMutable); } }); - return container; - } - protected JPanel createCustomEditorsPane() { - JPanel container = new JPanel(new BorderLayout()); - container.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Custom_Settings_Title"))); - - uiTabbedPane = new UITabbedPane(); - uiTabbedPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 1)); - container.add(uiTabbedPane, BorderLayout.NORTH); - - return container; - } - public void addCustomEditorPane(String title, JComponent component) { - component.setPreferredSize(new Dimension(317, 239)); - uiTabbedPane.addTab(title, component); - } - protected JPanel createCellStyleSettingPane() { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - cellStyleSettingPane = new CellStyleListEditPane(); - cellStyleSettingPane.registerAttrChangeListener(new AttributeChangeListener() { - @Override - public void attributeChange() { - valueChangeAction(); - } - }); - container.add(cellStyleSettingPane); - return container; - } - protected JPanel createChartStyleSettingPane() { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - chartStyleSettingPane = new ChartStyleEditPane(); - container.add(chartStyleSettingPane); - return container; + return themeEditorPane; } public abstract TemplateThemePreviewPane createThemePreviewPane(); + public abstract TemplateThemeEditorPane createThemeEditorPane(); - public void onColorSchemeChanged(List colors) { - colorListExtendedPane.populate(colors); - FineColorManager.FineColorReplaceByColorScheme replaceByColorScheme = new FineColorManager.FineColorReplaceByColorScheme(colors); - T theme = updateBean(); + public void populateBean(T theme) { + isPopulating = true; - FineColorFlushUtils.replaceCacheObject(theme, replaceByColorScheme); - FineColorManager.traverse(theme, replaceByColorScheme); - populateBean4CustomEditors(theme); - //图表渐变色 - chartStyleSettingPane.populateGradientBar(colors); + isMutable = theme.isMutable(); - themePreviewPane.refresh(theme); - this.repaint(); - } + themeEditorPane.populateBean(theme); - public void populateBean(T theme) { - this.theme = theme; - isPopulating = true; + themePreviewPane.refresh(theme); String name = theme.getName(); - currentIsNewTheme = config.cachedFetch(name) == null; - - nameTextField.setText(name); - nameTextField.setEnabled(StringUtils.isEmpty(name)); if (saveButton != null) { - saveButton.setEnabled(theme.isMutable() && !currentIsNewTheme); + saveButton.setEnabled(isMutable); } if (saveAsButton != null) { - saveAsButton.setEnabled(!currentIsNewTheme); + saveAsButton.setEnabled(StringUtils.isNotEmpty(name)); } - - colorListPane.populate(theme.getColorScheme().getColors()); - colorListExtendedPane.populate(colorListPane.update()); - - populateBean4CustomEditors(theme); - - themePreviewPane.refresh(theme); isPopulating = false; } - protected void populateBean4CustomEditors(T theme) { - cellStyleSettingPane.populateBean(theme.getCellStyleList()); - chartStyleSettingPane.populateBean(theme.getChartStyle()); - } - public T updateBean() { - if (theme == null) { - theme = config.createNewTheme(); - } - - theme.setName(this.nameTextField.getText()); + T theme = themeEditorPane.updateBean(); Image thumbnailImage = themePreviewPane.createThumbnailImage(); if (thumbnailImage != null) { @@ -372,24 +151,55 @@ public abstract class TemplateThemeProfilePane extends theme.setThumbnail(thumbnail); } - ThemedCellStyleList cellStyleConfig = this.cellStyleSettingPane.updateBean(); - theme.setCellStyleList(cellStyleConfig); - - ThemedColorScheme colorScheme = theme.getColorScheme(); - colorScheme.setColors(this.colorListPane.update()); - theme.setColorScheme(colorScheme); - - theme.setChartStyle(this.chartStyleSettingPane.updateBean()); - - updateBean(theme); return theme; } - public List getCurrentColorScheme() { - return colorListPane.update(); + public TemplateThemeEditorPane getThemeEditorPane() { + return themeEditorPane; } - protected abstract void updateBean(T theme); + public void save(CallBackAdaptor callBack) { + T theme; + try { + theme = (T) updateBean().clone(); + } catch (CloneNotSupportedException ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + return; + } + save(theme, callBack); + } + public void save(String name, CallBackAdaptor callBack) { + T theme = null; + try { + theme = (T) updateBean().clone(); + } catch (CloneNotSupportedException ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + return; + } + theme.setName(name); + save(theme, callBack); + } + private void save(T theme, CallBackAdaptor callBack) { + theme.setRemovable(true); + theme.setMutable(true); + config.addTheme(theme, true, new CallBackAdaptor() { + @Override + public void afterCommit() { + super.afterCommit(); + themeEditorPane.setThemeNameEditable(false); + callBack.afterCommit(); + } + + @Override + public void afterRollback() { + super.afterRollback(); + FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this), + i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), + i18nText("Fine-Design_Basic_Alert"), + JOptionPane.WARNING_MESSAGE); + } + }); + } public UIButton createSaveButton() { saveButton = new UIButton(); @@ -398,29 +208,15 @@ public abstract class TemplateThemeProfilePane extends saveButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - T theme = updateBean(); - boolean canBeSaved = checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, true, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); - if (canBeSaved && theme != null) { - theme.setName(nameTextField.getText()); - config.addTheme(theme, true, new CallBackAdaptor() { - @Override - public void afterCommit() { - super.afterCommit(); - currentIsNewTheme = false; - nameTextField.setEnabled(false); - saveAsButton.setEnabled(true); - } - - @Override - public void afterRollback() { - super.afterRollback(); - FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this), - i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), - i18nText("Fine-Design_Basic_Alert"), - JOptionPane.WARNING_MESSAGE); - } - }); - } + save(new CallBackAdaptor() { + @Override + public void afterCommit() { + super.afterCommit(); + saveButton.setEnabled(false); + saveAsButton.setEnabled(true); + DesignerToastMsgUtil.toastPrompt(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Save_Successfully")); + } + }); } }); return saveButton; @@ -441,7 +237,7 @@ public abstract class TemplateThemeProfilePane extends private class SaveAsDialog extends JDialog { private final TemplateThemeProfileDialog parent; - private UITextField nameTextField; + private AutoCheckThemeNameTextField nameTextField; private UILabel nameErrorLabel; private UIButton confirmButton; @@ -467,6 +263,18 @@ public abstract class TemplateThemeProfilePane extends } private void initializeComponents() { + nameTextField = new AutoCheckThemeNameTextField<>(); + nameTextField.setThemeConfig(config); + nameTextField.setPreferredSize(new Dimension(180, 20)); + nameTextField.setNameCheckListener(new AutoCheckTextField.CheckListener() { + @Override + public void onChecked(String error, boolean valid) { + nameErrorLabel.setVisible(StringUtils.isNotEmpty(error)); + nameErrorLabel.setText(error); + confirmButton.setEnabled(valid); + } + }); + nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED); nameErrorLabel.setBorder(BorderFactory.createEmptyBorder(10, 20, 0, 0)); @@ -475,47 +283,16 @@ public abstract class TemplateThemeProfilePane extends confirmButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - saveAsNew(nameTextField.getText()); - } - }); - - nameTextField = new UITextField(); - nameTextField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(true, false, true, true, nameTextField, nameErrorLabel, confirmButton); - } - } - - @Override - public void removeUpdate(DocumentEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(true, false, true, true, nameTextField, nameErrorLabel, confirmButton); - } - } - - @Override - public void changedUpdate(DocumentEvent e) { - - } - }); - nameTextField.addFocusListener(new FocusAdapter() { - @Override - public void focusGained(FocusEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(true, false, true, true, nameTextField, nameErrorLabel, confirmButton); - } - } - - @Override - public void focusLost(FocusEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(true, true, true, true, nameTextField, nameErrorLabel, confirmButton); - } + save(nameTextField.getText(), new CallBackAdaptor() { + @Override + public void afterCommit() { + super.afterCommit(); + exit(); + parent.exit(); + } + }); } }); - nameTextField.setPreferredSize(new Dimension(180, 20)); } private JPanel createActionsContainer() { @@ -549,82 +326,8 @@ public abstract class TemplateThemeProfilePane extends return container; } - private void saveAsNew(String name) { - T newThemeObject = null; - try { - newThemeObject = (T) updateBean().clone(); - } catch (CloneNotSupportedException ex) { - FineLoggerFactory.getLogger().error(ex.getMessage(), ex); - return; - } - boolean canBeSaved = checkThemeCanBeSavedAndUpdateUI(true, true, true, true, nameTextField, nameErrorLabel, confirmButton); - if (canBeSaved && newThemeObject != null) { - newThemeObject.setName(name); - newThemeObject.setRemovable(true); - newThemeObject.setMutable(true); - config.addTheme(newThemeObject, true, new CallBackAdaptor() { - @Override - public void afterCommit() { - super.afterCommit(); - exit(); - parent.exit(); - } - - @Override - public void afterRollback() { - super.afterRollback(); - FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this), - i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), - i18nText("Fine-Design_Basic_Alert"), - JOptionPane.WARNING_MESSAGE); - } - }); - } - } - public void exit() { this.dispose(); } } - - private boolean isThemeNameEmpty(String name) { - return StringUtils.isEmpty(name); - } - private boolean isThemeNameDuplicated(String name) { - return config.cachedFetch(name) != null; - } - private boolean checkThemeCanBeSavedAndUpdateUI( - boolean checkEmpty, - boolean displayEmptyTip, - boolean checkDuplicated, - boolean displayDuplicatedTip, - UITextField textField, - UILabel errorLabel, UIButton... actionButtons) { - String name = textField.getText(); - - boolean valid = true; - errorLabel.setText(StringUtils.EMPTY); - if (checkEmpty && isThemeNameEmpty(name)) { - valid = false; - if (displayEmptyTip) { - errorLabel.setText(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Empty_Name_Error_Tip")); - } - } else if (checkDuplicated && isThemeNameDuplicated(name)) { - valid = false; - if (displayDuplicatedTip) { - errorLabel.setText(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Duplicated_Name_Error_Tip")); - } - } - - errorLabel.setVisible(!valid); - if (actionButtons != null && actionButtons.length > 0) { - for (UIButton button : actionButtons) { - if (button != null) { - button.setEnabled(valid); - } - } - } - - return valid; - } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java index 3a6a9d3838..fe31bd13ac 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java @@ -51,7 +51,7 @@ public class TemplateThemeProfileDialog extends Templat public static List getEditingColorScheme() { if (currentVisibleProfilePane != null) { - return currentVisibleProfilePane.getCurrentColorScheme(); + return currentVisibleProfilePane.getThemeEditorPane().getCurrentColorScheme(); } return null; } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java index 53e216b0d6..de62a195d4 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java @@ -2,8 +2,7 @@ package com.fr.design.mainframe.theme.edit; import com.fr.base.theme.settings.ThemedComponentStyle; import com.fr.design.designer.IntervalConstants; -import com.fr.design.dialog.AttrScrollPane; -import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.style.ComponentBodyStylePane; import com.fr.design.gui.style.ComponentIntegralStylePane; import com.fr.design.gui.style.ComponentTitleStylePane; @@ -18,10 +17,9 @@ import com.fr.general.act.BorderPacker; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JPanel; -import javax.swing.JScrollPane; +import javax.swing.JTextArea; import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Dimension; /** * @author Starryi @@ -50,7 +48,8 @@ public class ComponentStyleEditPane extends JPanel { }, new JComponent[] { createTabContainer(componentTitleStylePane), createTabContainer(componentBodyStylePane), createTabContainer(componentIntegralStylePane) } ); - add(content, BorderLayout.NORTH); + content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + add(content, BorderLayout.CENTER); } public void populateBean(ThemedComponentStyle style) { @@ -115,21 +114,20 @@ public class ComponentStyleEditPane extends JPanel { } private JComponent createTabContainer(final JPanel component) { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - container.setPreferredSize(new Dimension(container.getPreferredSize().width, 220)); + JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane(); JPanel tipLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); tipLabelPane.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); - UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Component_Style_Tip"), new Color(153, 153, 153)); + JTextArea tipLabel = LabelUtils.createAutoWrapLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Component_Style_Tip"), new Color(153, 153, 153)); tipLabelPane.add(tipLabel); - container.add(tipLabelPane, BorderLayout.NORTH); - - container.add(new AttrScrollPane() { - @Override - protected JPanel createContentPane() { - return component; - } - }, BorderLayout.CENTER); + content.add(tipLabelPane, BorderLayout.NORTH); + content.add(component, BorderLayout.CENTER); + + UIScrollPane scrollPane = new UIScrollPane(content); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.add(scrollPane, BorderLayout.CENTER); return container; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListPane.java index adeca3d7a5..5c282033f0 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListPane.java @@ -40,6 +40,8 @@ public class ColorListPane extends JPanel implements UIObserver { private final EventListenerList colorChangeListenerList = new EventListenerList(); private UIObserverListener uiObserverListener; + private boolean isPopulating = false; + public ColorListPane() { this(DEFAULT_COLOR_COUNT, DEFAULT_COLOR_SIZE, DEFAULT_COLOR_GAP); } @@ -61,6 +63,9 @@ public class ColorListPane extends JPanel implements UIObserver { colorButton.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { + if (isPopulating) { + return; + } colorList.set(index, colorButton.getSelectObject()); fireColorStateChanged(); } @@ -88,6 +93,7 @@ public class ColorListPane extends JPanel implements UIObserver { } public void populate(List colors) { + isPopulating = true; colorList.clear(); for (int i = 0; i < colors.size(); i++) { Color color = colors.get(i); @@ -96,6 +102,7 @@ public class ColorListPane extends JPanel implements UIObserver { colorButtons.get(i).setSelectObject(color); } } + isPopulating = false; } public List update() { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java index 2b099ed306..13769cfc64 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java @@ -3,6 +3,9 @@ package com.fr.design.mainframe.theme.edit.ui; import com.fr.design.gui.ilable.UILabel; import com.fr.general.FRFont; +import javax.swing.BorderFactory; +import javax.swing.JTextArea; +import javax.swing.plaf.basic.BasicTextAreaUI; import java.awt.Color; import java.awt.Font; @@ -26,4 +29,20 @@ public class LabelUtils { uiLabel.setFont(newFont); return uiLabel; } + + public static JTextArea createAutoWrapLabel(String title, Color color) { + JTextArea tipLabel = new JTextArea(); + tipLabel.setUI(new BasicTextAreaUI()); + tipLabel.setForeground(color); + Font newFont = FRFont.getInstance(tipLabel.getFont().getFontName(), Font.PLAIN, 12); + tipLabel.setFont(newFont); + tipLabel.setBorder(BorderFactory.createEmptyBorder()); + tipLabel.setEnabled(false); + tipLabel.setText(title); + tipLabel.setLineWrap(true); + tipLabel.setWrapStyleWord(true); + tipLabel.setOpaque(false); + tipLabel.setBackground(null); + return tipLabel; + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java index 3f4667e111..c1c8371674 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java @@ -25,7 +25,6 @@ public class TabbedPane extends JPanel { public TabbedPane(String[] names, JComponent[] panes) { setLayout(FRGUIPaneFactory.createBorderLayout()); - setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); for (JComponent pane :panes) { pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java index 231233196d..281624ef32 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java @@ -64,8 +64,8 @@ public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreview northPane.add(bigTitleCell, BorderLayout.NORTH); CornerPreviewCell cornerCell = new CornerPreviewCell(new String[]{Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Product"), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Data"), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Statistical_Dimension")}, - new Point2D[]{new Point(159, 71), new Point(226, 49)}); - cornerCell.setPreferredSize(new Dimension(226, 71)); + new Point2D[]{new Point(159, 71), new Point(225, 49)}); + cornerCell.setPreferredSize(new Dimension(225, 71)); headerCellList.add(cornerCell); northPane.add(cornerCell, BorderLayout.WEST); JPanel centerPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane(); @@ -99,7 +99,7 @@ public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreview JPanel gridPane = new UINoOpaquePanel(new GridLayout(5, 1)); for (int i = 0; i < 5; i++) { PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Apple_Juice")); - cell.setPreferredSize(new Dimension(114, 31)); + cell.setPreferredSize(new Dimension(113, 31)); headerCellList.add(cell); gridPane.add(cell); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckTextField.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckTextField.java new file mode 100644 index 0000000000..9ce5a3d5d3 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckTextField.java @@ -0,0 +1,100 @@ +package com.fr.design.mainframe.theme.ui; + +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.stable.StringUtils; + +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/18 + */ +public class AutoCheckTextField extends UITextField implements DocumentListener, FocusListener { + private DuplicateChecker duplicatedChecker; + private CheckListener checkListener; + + public AutoCheckTextField() { + getDocument().addDocumentListener(this); + addFocusListener(this); + } + + public void setDuplicatedChecker(DuplicateChecker checker) { + this.duplicatedChecker = checker; + } + public void setNameCheckListener(CheckListener checkListener) { + this.checkListener = checkListener; + } + + private boolean isEmpty(String name) { + return StringUtils.isEmpty(name); + } + private boolean isDuplicated(String name) { + if (duplicatedChecker != null) { + return duplicatedChecker.isDuplicated(name); + } + return false; + } + private boolean checkValid(boolean notifyEmptyTip) { + String name = getText(); + + String error = StringUtils.EMPTY; + boolean valid = true; + if (isEditable()) { + if (isEmpty(name)) { + valid = false; + if (notifyEmptyTip) { + error = Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Empty_Name_Error_Tip"); + } + } else if (isDuplicated(name)) { + valid = false; + error = Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Duplicated_Name_Error_Tip"); + } + } + + if (checkListener != null) { + checkListener.onChecked(error, valid); + } + + return valid; + } + public boolean checkValid() { + return checkValid(true); + } + + @Override + public void insertUpdate(DocumentEvent e) { + checkValid(false); + } + + @Override + public void removeUpdate(DocumentEvent e) { + checkValid(false); + } + + @Override + public void changedUpdate(DocumentEvent e) { + + } + + @Override + public void focusGained(FocusEvent e) { + checkValid(false); + } + + @Override + public void focusLost(FocusEvent e) { + checkValid(true); + } + + public interface CheckListener { + void onChecked(String error, boolean valid); + } + public interface DuplicateChecker { + boolean isDuplicated(String name); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckThemeNameTextField.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckThemeNameTextField.java new file mode 100644 index 0000000000..804c8493d2 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckThemeNameTextField.java @@ -0,0 +1,26 @@ +package com.fr.design.mainframe.theme.ui; + +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/18 + */ +public class AutoCheckThemeNameTextField extends AutoCheckTextField { + private TemplateThemeConfig config; + + public AutoCheckThemeNameTextField() { + setDuplicatedChecker(new DuplicateChecker() { + @Override + public boolean isDuplicated(String name) { + return config != null && config.contains(name); + } + }); + } + + public void setThemeConfig(TemplateThemeConfig config) { + this.config = config; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java index d8e5b4a57e..cfc4483c95 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java @@ -40,6 +40,7 @@ import com.fr.design.actions.server.GlobalParameterAction; import com.fr.design.actions.server.GlobalTableDataAction; import com.fr.design.actions.server.PlatformManagerAction; import com.fr.design.actions.server.PluginManagerAction; +import com.fr.design.base.mode.DesignModeContext; import com.fr.design.file.NewTemplatePane; import com.fr.design.fun.MenuHandler; import com.fr.design.fun.OemProcessor; @@ -407,7 +408,9 @@ public abstract class ToolBarMenuDock { menuDef.addShortCut(new OpenRecentReportMenuDef()); - addCloseCurrentTemplateAction(menuDef); + if (!DesignModeContext.isDuchampMode()) { + addCloseCurrentTemplateAction(menuDef); + } scs = plus.shortcut4FileMenu(); if (!ArrayUtils.isEmpty(scs)) { @@ -491,10 +494,12 @@ public abstract class ToolBarMenuDock { if (!DesignerMode.isAuthorityEditing()) { addPluginManagerAction(menuDef); - menuDef.addShortCut( - new FunctionManagerAction(), - new GlobalParameterAction() - ); + menuDef.addShortCut(new FunctionManagerAction()); + + if (!DesignModeContext.isDuchampMode()) { + menuDef.addShortCut(new GlobalParameterAction()); + } + } diff --git a/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java b/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java index 8c7ed5ac5a..09fa2bbc08 100644 --- a/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java +++ b/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java @@ -17,15 +17,17 @@ import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; import com.teamdev.jxbrowser.chromium.events.ScriptContextListener; import com.teamdev.jxbrowser.chromium.swing.BrowserView; +import com.teamdev.jxbrowser.event.Observer; import javax.swing.JDialog; import javax.swing.SwingUtilities; import javax.swing.WindowConstants; -import java.util.Map; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.io.File; +import java.util.Map; /** * @author richie @@ -157,6 +159,38 @@ public class ModernUIPane extends BasicPane { return null; } + public void disposeBrowser() { + + if(browser != null) { + browser.dispose(); + browser = null; + } + + } + + public void clearCache() { + if (browser != null) { + browser.getCacheStorage().clearCache(); + File file = new File(browser.getContext().getCacheDir()); + if (file.exists()) { + file.delete(); + } + } + } + + public void executeJavaScript(String javaScript) { + if (browser != null) { + browser.executeJavaScript(javaScript); + } + } + + public JSValue executeJavaScriptAndReturnValue(String javaScript) { + if (browser != null) { + return browser.executeJavaScriptAndReturnValue(javaScript); + } + return null; + } + public static class Builder implements BuilderDiff { private ModernUIPane pane; @@ -293,6 +327,12 @@ public class ModernUIPane extends BasicPane { return this; } + @Override + public Builder prepareForV7(Class event, Observer listener) { + // do nothing + return this; + } + public ModernUIPane build() { return pane; } diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java b/designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java index 33c817c948..9e6168514f 100644 --- a/designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java @@ -4,6 +4,7 @@ import com.fr.design.ui.ModernUIPane; import com.teamdev.jxbrowser.browser.callback.InjectJsCallback; import com.teamdev.jxbrowser.chromium.events.LoadListener; import com.teamdev.jxbrowser.chromium.events.ScriptContextListener; +import com.teamdev.jxbrowser.event.Observer; /** * 封装jxbrwoser v6/v7的构建方式的差异 @@ -20,5 +21,6 @@ public interface BuilderDiff { ModernUIPane.Builder prepareForV7(InjectJsCallback callback); + ModernUIPane.Builder prepareForV7(Class event, Observer listener); } diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java b/designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java index 5ae56627e9..68b8950f7c 100644 --- a/designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java @@ -11,6 +11,17 @@ import com.fr.stable.os.OperatingSystem; public class ModernUIPaneFactory { public static ModernUIPane.Builder modernUIPaneBuilder() { + + if (isV7()) { + return new NewModernUIPane.Builder<>(); + } else { + return new ModernUIPane.Builder<>(); + } + + } + + public static boolean isV7() { + // 7.15的class不存在时 走老版本 boolean hasJxBrowserV7_15 = true; try { @@ -18,10 +29,8 @@ public class ModernUIPaneFactory { } catch (ClassNotFoundException e) { hasJxBrowserV7_15 = false; } - if (OperatingSystem.isWindows() && hasJxBrowserV7_15) { - return new NewModernUIPane.Builder<>(); - } else { - return new ModernUIPane.Builder<>(); - } + + return OperatingSystem.isWindows() && hasJxBrowserV7_15; + } } diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java b/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java index 33747d3f15..d755d4e05f 100644 --- a/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java @@ -15,6 +15,7 @@ import com.teamdev.jxbrowser.chromium.events.ScriptContextListener; import com.teamdev.jxbrowser.engine.Engine; import com.teamdev.jxbrowser.engine.EngineOptions; import com.teamdev.jxbrowser.engine.RenderingMode; +import com.teamdev.jxbrowser.event.Observer; import com.teamdev.jxbrowser.js.JsObject; import com.teamdev.jxbrowser.net.Scheme; import com.teamdev.jxbrowser.view.swing.BrowserView; @@ -80,30 +81,33 @@ public class NewModernUIPane extends ModernUIPane { private void showDebuggerDialog() { JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(this)); - Engine engine = Engine.newInstance( - EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED) - .addSwitch("--disable-google-traffic") - .remoteDebuggingPort(9222).build()); - Browser debugger = engine.newBrowser(); + + Browser debugger = browser.engine().newBrowser(); BrowserView debuggerView = BrowserView.newInstance(debugger); dialog.add(debuggerView, BorderLayout.CENTER); dialog.setSize(new Dimension(800, 400)); GUICoreUtils.centerWindow(dialog); dialog.setVisible(true); dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + browser.devTools().remoteDebuggingUrl().ifPresent(url -> { debugger.navigation().loadUrl(url); }); } private void initializeBrowser() { - EngineOptions options; + EngineOptions.Builder builder; if (scheme != null && requestCallback != null) { - options = EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic").addScheme(scheme, requestCallback).build(); - } else { - options = EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic").build(); + builder = EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic").addScheme(scheme, requestCallback); + } else { + builder = EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic"); + } + + if (DesignerEnvManager.getEnvManager().isOpenDebug()) { + builder.remoteDebuggingPort(9222); } - Engine engine = Engine.newInstance(options); + + Engine engine = Engine.newInstance(builder.build()); browser = engine.newBrowser(); // 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的 @@ -161,6 +165,29 @@ public class NewModernUIPane extends ModernUIPane { return null; } + public void disposeBrowser() { + + if (browser != null) { + browser.close(); + browser = null; + } + + } + + public void clearCache() { + if (browser != null) { + browser.engine().httpCache().clear(); + } + } + + public void executeJavaScript(String javaScript) { + if (browser != null) { + browser.mainFrame().ifPresent(frame -> { + frame.executeJavaScript(javaScript); + }); + } + } + public static class Builder extends ModernUIPane.Builder { private NewModernUIPane pane = new NewModernUIPane<>(); @@ -191,7 +218,7 @@ public class NewModernUIPane extends ModernUIPane { @Override public NewModernUIPane.Builder withURL(final String url) { pane.scheme = Scheme.of("file"); - pane.requestCallback = new NxComplexInterceptRequestCallback(null); + pane.requestCallback = new NxComplexInterceptRequestCallback(null); pane.browser.navigation().loadUrl(url); return this; } @@ -301,6 +328,14 @@ public class NewModernUIPane extends ModernUIPane { return prepare(callback); } + @Override + public ModernUIPane.Builder prepareForV7(Class event, Observer listener) { + + pane.browser.navigation().on(event, listener); + + return this; + } + @Override public NewModernUIPane build() { return pane; diff --git a/designer-base/src/main/java/com/fr/design/update/push/DesignerPushUpdateManager.java b/designer-base/src/main/java/com/fr/design/update/push/DesignerPushUpdateManager.java index 6214f1cfa9..425f164543 100644 --- a/designer-base/src/main/java/com/fr/design/update/push/DesignerPushUpdateManager.java +++ b/designer-base/src/main/java/com/fr/design/update/push/DesignerPushUpdateManager.java @@ -60,7 +60,7 @@ public class DesignerPushUpdateManager { private String getFullLatestVersion() { try { - String url = CloudCenter.getInstance().acquireUrlByKind("jar10.update"); + String url = CloudCenter.getInstance().acquireUrlByKind("jar11.update"); if(StringUtils.isBlank(url)){ return StringUtils.EMPTY; } diff --git a/designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java b/designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java index 3c91ebf145..9a849ad4e9 100644 --- a/designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java +++ b/designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java @@ -350,7 +350,7 @@ public class UpdateMainDialog extends UIDialog { new SwingWorker() { @Override protected JSONObject doInBackground() throws Exception { - return new JSONObject(HttpToolbox.get(CloudCenter.getInstance().acquireUrlByKind("jar10.update"))); + return new JSONObject(HttpToolbox.get(CloudCenter.getInstance().acquireUrlByKind("jar11.update"))); } @Override diff --git a/designer-base/src/main/java/com/fr/design/utils/gui/AdjustWorkBookDefaultStyleUtils.java b/designer-base/src/main/java/com/fr/design/utils/gui/AdjustWorkBookDefaultStyleUtils.java new file mode 100644 index 0000000000..abae997e39 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/utils/gui/AdjustWorkBookDefaultStyleUtils.java @@ -0,0 +1,46 @@ +package com.fr.design.utils.gui; + +import com.fr.base.Style; +import com.fr.base.background.ColorBackground; +import com.fr.design.base.mode.DesignModeContext; +import com.fr.report.cell.CellElement; +import com.fr.report.cell.FloatElement; + +import java.awt.Color; + +/** + * @author shine + * @version 10.0 + * Created by shine on 2021/9/6 + */ +public class AdjustWorkBookDefaultStyleUtils { + + private static final Color TEMPLATE_BACKGROUND = new Color(16, 11, 43); + private static final Color CELL_ELEMENT_BORDER = new Color(110, 110, 110); + + public static void adjustCellElement(CellElement cellElement) { + if (DesignModeContext.isDuchampMode()) { + Style style = cellElement.getStyle(); + style = style.deriveFRFont(style.getFRFont().applyForeground(Color.WHITE)); + style = style.deriveBorder(0, CELL_ELEMENT_BORDER, + 0, CELL_ELEMENT_BORDER, + 0, CELL_ELEMENT_BORDER, + 0, CELL_ELEMENT_BORDER); + cellElement.setStyle(style); + } + } + + public static void adjustFloatElement(FloatElement floatElement) { + if (DesignModeContext.isDuchampMode()) { + Style style = floatElement.getStyle(); + style = style.deriveBackground(ColorBackground.getInstance(TEMPLATE_BACKGROUND)); + style = style.deriveFRFont(style.getFRFont().applyForeground(Color.WHITE)); + floatElement.setStyle(style); + } + } + + public static Color adjustBack(Color color) { + return DesignModeContext.isDuchampMode() ? TEMPLATE_BACKGROUND : color; + } + +} 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 a89e367d64..ac75786314 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 @@ -38,7 +38,6 @@ import com.fr.stable.Constants; import com.fr.stable.OperatingSystem; import com.fr.stable.StringUtils; -import java.awt.Container; import javax.swing.AbstractButton; import javax.swing.Action; import javax.swing.BorderFactory; @@ -67,10 +66,13 @@ import javax.swing.tree.TreePath; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; +import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import java.awt.GridLayout; import java.awt.Image; import java.awt.Point; @@ -82,8 +84,6 @@ import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -176,7 +176,7 @@ public final class GUICoreUtils { if (style.getBackground() instanceof ColorBackground) { textField.setBackground(((ColorBackground) style.getBackground()).getColor()); } else { - textField.setBackground(Color.WHITE); + textField.setBackground(AdjustWorkBookDefaultStyleUtils.adjustBack(Color.WHITE)); } } diff --git a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java index 2dfbda4f53..c21c82c75a 100644 --- a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java +++ b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java @@ -29,6 +29,9 @@ import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.DesignerFrame; import com.fr.design.mainframe.JTemplate; import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.event.Event; +import com.fr.event.EventDispatcher; +import com.fr.event.Listener; import com.fr.file.filetree.FileNode; import com.fr.file.filter.ChooseFileFilter; import com.fr.file.filter.FILEFilter; @@ -45,6 +48,8 @@ import com.fr.stable.os.windows.WindowsDetector; import com.fr.stable.project.ProjectConstants; import com.fr.workspace.WorkContext; +import com.fr.workspace.Workspace; +import com.fr.workspace.WorkspaceEvent; import javax.swing.AbstractAction; import javax.swing.AbstractListModel; import javax.swing.ActionMap; @@ -66,7 +71,6 @@ import javax.swing.ListModel; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; -import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; @@ -1334,6 +1338,12 @@ public class FILEChooserPane extends BasicPane { LocationButtonPane.this.repaint(10); } }); + EventDispatcher.listen(WorkspaceEvent.AfterSwitch, new Listener() { + @Override + public void on(Event event, Workspace param) { + setPopDir(null); + } + }); } public void highLightButton(FILE dir) { diff --git a/designer-base/src/main/resources/com/fr/design/images/transparent_background.png b/designer-base/src/main/resources/com/fr/design/images/transparent_background.png index cfb233f46e..4f942536f8 100644 Binary files a/designer-base/src/main/resources/com/fr/design/images/transparent_background.png and b/designer-base/src/main/resources/com/fr/design/images/transparent_background.png differ