From 3511fcf79061aa0fabfecc00a6691539cdc72a5e Mon Sep 17 00:00:00 2001 From: neil <459208047@qq.com> Date: Thu, 7 Jun 2018 15:16:36 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E6=97=A0JIRA=E4=BB=BB=E5=8A=A1=EF=BC=8C?= =?UTF-8?q?=E6=94=B9=E4=B8=8BSQLite=E9=BB=98=E8=AE=A4=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/com/fr/design/data/datapane/connect/JDBCDefPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designer-base/src/com/fr/design/data/datapane/connect/JDBCDefPane.java b/designer-base/src/com/fr/design/data/datapane/connect/JDBCDefPane.java index f5a63d47a..a50cd4f5a 100644 --- a/designer-base/src/com/fr/design/data/datapane/connect/JDBCDefPane.java +++ b/designer-base/src/com/fr/design/data/datapane/connect/JDBCDefPane.java @@ -54,7 +54,7 @@ public class JDBCDefPane extends JPanel { jdbcMap.put("Access", new DriverURLName[]{new DriverURLName("sun.jdbc.odbc.JdbcOdbcDriver", "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=")}); jdbcMap.put("Derby", new DriverURLName[]{new DriverURLName("org.apache.derby.jdbc.ClientDriver", "jdbc:derby://localhost:1527/")}); jdbcMap.put("Postgre", new DriverURLName[]{new DriverURLName("org.postgresql.Driver", "jdbc:postgresql://localhost:5432/")}); - jdbcMap.put("SQLite", new DriverURLName[]{new DriverURLName("org.sqlite.JDBC", "jdbc:sqlite://${ENV_HOME}/../FRDemo.db")}); + jdbcMap.put("SQLite", new DriverURLName[]{new DriverURLName("org.sqlite.JDBC", "jdbc:sqlite://${ENV_HOME}/../help/FRDemo.db")}); } private UIButton dbtypeButton; From f169fb0b0fe07b3ebf32bb10d24f8c79d696622b Mon Sep 17 00:00:00 2001 From: zack Date: Thu, 7 Jun 2018 16:26:40 +0800 Subject: [PATCH 2/9] =?UTF-8?q?REPORT-8357=20=20.0=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E7=9A=84=E5=8A=9F=E8=83=BD=E4=B8=8Ebug=20pat?= =?UTF-8?q?ch=E5=88=B010.0=20=E5=9B=BE=E7=89=87=E5=8E=8B=E7=BC=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/com/fr/design/DesignerEnvManager.java | 12 + .../design/gui/frpane/ImgChooseWrapper.java | 154 ++++++ .../ImageBackgroundQuickPane.java | 38 +- .../backgroundpane/ImagePreviewPane.java | 514 +++++++++--------- .../background/image/ExpandFileChooser.java | 196 +++++++ .../background/image/ImageFileChooser.java | 31 +- .../background/image/ImagePreviewPane.java | 118 ++-- .../background/image/ImagePreviewer.java | 40 ++ .../background/image/ImageSelectPane.java | 16 +- .../background/impl/ImageBackgroundPane.java | 56 +- .../impl/ImageBackgroundPane4Browser.java | 13 - .../impl/ImageButtonBackgroundPane.java | 22 +- .../src/com/fr/design/utils/ImageUtils.java | 285 ++++++++++ .../com/fr/design/headerfooter/ImagePane.java | 53 +- 14 files changed, 1105 insertions(+), 443 deletions(-) create mode 100644 designer-base/src/com/fr/design/gui/frpane/ImgChooseWrapper.java create mode 100644 designer-base/src/com/fr/design/style/background/image/ExpandFileChooser.java create mode 100644 designer-base/src/com/fr/design/style/background/image/ImagePreviewer.java create mode 100644 designer-base/src/com/fr/design/utils/ImageUtils.java diff --git a/designer-base/src/com/fr/design/DesignerEnvManager.java b/designer-base/src/com/fr/design/DesignerEnvManager.java index 634240489..6517e705e 100644 --- a/designer-base/src/com/fr/design/DesignerEnvManager.java +++ b/designer-base/src/com/fr/design/DesignerEnvManager.java @@ -148,6 +148,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { private boolean isHttps = false; private static List mapWorkerList = new ArrayList(); + private boolean imageCompress = false;//图片压缩 /** * DesignerEnvManager. @@ -1412,6 +1413,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { this.setOracleSystemSpace(reader.getAttrAsBoolean("useOracleSystemSpace", true)); this.setCachingTemplateLimit(reader.getAttrAsInt("cachingTemplateLimit", CACHINGTEMPLATE_LIMIT)); this.setJoinProductImprove(reader.getAttrAsBoolean("joinProductImprove", true)); + this.setImageCompress(reader.getAttrAsBoolean("imageCompress", true)); this.setAutoBackUp(reader.getAttrAsBoolean("autoBackUp", true)); this.setTemplateTreePaneExpanded(reader.getAttrAsBoolean("templateTreePaneExpanded", false)); // peter:读取webinfLocation @@ -1637,6 +1639,9 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { if (!this.isJoinProductImprove()) { writer.attr("joinProductImprove", this.isJoinProductImprove()); } + if (!this.isImageCompress()) { + writer.attr("imageCompress", this.isImageCompress()); + } if (!this.isAutoBackUp()) { writer.attr("autoBackUp", this.isAutoBackUp()); } @@ -1884,4 +1889,11 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { return this; } } + public boolean isImageCompress() { + return imageCompress; + } + + public void setImageCompress(boolean imageCompress) { + this.imageCompress = imageCompress; + } } \ No newline at end of file diff --git a/designer-base/src/com/fr/design/gui/frpane/ImgChooseWrapper.java b/designer-base/src/com/fr/design/gui/frpane/ImgChooseWrapper.java new file mode 100644 index 000000000..95073bf42 --- /dev/null +++ b/designer-base/src/com/fr/design/gui/frpane/ImgChooseWrapper.java @@ -0,0 +1,154 @@ +package com.fr.design.gui.frpane; + +import com.fr.base.BaseUtils; +import com.fr.base.Style; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.style.background.image.ImageFileChooser; +import com.fr.design.style.background.image.ImagePreviewer; +import com.fr.design.utils.ImageUtils; +import com.fr.general.ImageWithSuffix; +import com.fr.general.Inter; +import com.fr.stable.CoreGraphHelper; +import com.fr.stable.StringUtils; + +import javax.swing.JFileChooser; +import javax.swing.SwingWorker; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.Image; +import java.io.File; + +/** + * 图片选择框包装类 + * Created by zack on 2018/3/9. + */ +public class ImgChooseWrapper { + private ImagePreviewer previewPane = null; + + private ImageFileChooser imageFileChooser = null; + + private Style imageStyle = null; + + private SwingWorker imageWorker; + private ChangeListener changeListener; + + private transient Image selectImage; + private UILabel imageSizeLabel; + + public static ImgChooseWrapper getInstance(ImagePreviewer previewPane, ImageFileChooser imageFileChooser, Style imageStyle) { + return getInstance(previewPane, imageFileChooser, imageStyle, null); + } + + public static ImgChooseWrapper getInstance(ImagePreviewer previewPane, ImageFileChooser imageFileChooser, Style imageStyle, ChangeListener changeListener) { + return new ImgChooseWrapper(previewPane, imageFileChooser, imageStyle, changeListener, null, null); + } + + public static ImgChooseWrapper getInstance(Image selectImage, UILabel imageSizeLabel, ImageFileChooser imageFileChooser) { + return new ImgChooseWrapper(null, imageFileChooser, null, null, selectImage, imageSizeLabel); + } + + private ImgChooseWrapper(ImagePreviewer previewPane, ImageFileChooser imageFileChooser, Style imageStyle, ChangeListener changeListener, Image selectImage, UILabel imageSizeLabel) { + this.previewPane = previewPane; + this.imageFileChooser = imageFileChooser; + this.imageStyle = imageStyle; + this.changeListener = changeListener; + this.selectImage = selectImage; + this.imageSizeLabel = imageSizeLabel; + } + + + public void setPreviewPane(ImagePreviewer previewPane) { + this.previewPane = previewPane; + } + + public ImageFileChooser getImageFileChooser() { + return imageFileChooser; + } + + public void setImageFileChooser(ImageFileChooser imageFileChooser) { + this.imageFileChooser = imageFileChooser; + } + + public Style getImageStyle() { + return imageStyle; + } + + public void setImageStyle(Style imageStyle) { + this.imageStyle = imageStyle; + } + + public SwingWorker getImageWorker() { + return imageWorker; + } + + public void setImageWorker(SwingWorker imageWorker) { + this.imageWorker = imageWorker; + } + + public void dealWithImageFile(int returnVal) { + if (returnVal != JFileChooser.CANCEL_OPTION) { + final File selectedFile = imageFileChooser.getSelectedFile(); + + if (selectedFile != null && selectedFile.isFile()) { + if (previewPane != null) { + previewPane.showLoading(); + } + if (imageWorker != null && !imageWorker.isDone()) { + imageWorker = null; + } + imageWorker = new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + ImageWithSuffix imageWithSuffix = null; + if (imageFileChooser.isCheckSelected()) { + imageWithSuffix = ImageUtils.defaultImageCompWithSuff(selectedFile); + } else { + Image image = BaseUtils.readImage(selectedFile.getPath()); + String type = ImageUtils.getImageType(selectedFile); + imageWithSuffix = new ImageWithSuffix(image, type); + } + + CoreGraphHelper.waitForImage(imageWithSuffix); + + if (previewPane != null) { + previewPane.setImageStyle(imageStyle); + previewPane.setImageWithSuffix(imageWithSuffix); + previewPane.repaint(); + } + checkLabelText(); + fireChangeListener(); + return null; + } + }; + imageWorker.execute(); + } else { + if (previewPane != null) { + previewPane.setImage(null); + } + + } + if (previewPane != null) { + previewPane.repaint(); + } + } + } + + private void fireChangeListener() { + if (this.changeListener != null) { + ChangeEvent evt = new ChangeEvent(this); + this.changeListener.stateChanged(evt); + } + } + + private void checkLabelText() { + if (imageSizeLabel == null) { + return; + } + if (selectImage == null) { + imageSizeLabel.setText(StringUtils.EMPTY); + } else { + imageSizeLabel.setText(selectImage.getWidth(null) + "x" + + selectImage.getHeight(null) + Inter.getLocText("px")); + } + } +} diff --git a/designer-base/src/com/fr/design/mainframe/backgroundpane/ImageBackgroundQuickPane.java b/designer-base/src/com/fr/design/mainframe/backgroundpane/ImageBackgroundQuickPane.java index 405e1fc18..8076f4784 100644 --- a/designer-base/src/com/fr/design/mainframe/backgroundpane/ImageBackgroundQuickPane.java +++ b/designer-base/src/com/fr/design/mainframe/backgroundpane/ImageBackgroundQuickPane.java @@ -1,30 +1,28 @@ package com.fr.design.mainframe.backgroundpane; -import com.fr.base.BaseUtils; import com.fr.base.Style; import com.fr.base.background.ImageFileBackground; import com.fr.base.frpx.pack.PictureCollection; -import com.fr.base.frpx.util.ImageIOHelper; -import com.fr.design.constants.UIConstants; import com.fr.design.border.UIRoundedBorder; +import com.fr.design.constants.UIConstants; import com.fr.design.event.UIObserverListener; +import com.fr.design.gui.frpane.ImgChooseWrapper; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UIButtonGroup; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; +import com.fr.design.style.background.image.ImageFileChooser; import com.fr.general.Background; import com.fr.general.Inter; import com.fr.stable.Constants; -import com.fr.stable.CoreGraphHelper; -import com.fr.design.style.background.image.ImageFileChooser; -import javax.swing.*; +import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.io.File; /** * @author zhou @@ -90,32 +88,14 @@ public class ImageBackgroundQuickPane extends BackgroundQuickPane { */ ActionListener selectPictureActionListener = new ActionListener() { - @Override public void actionPerformed(ActionEvent evt) { if (imageFileChooser == null) { imageFileChooser = new ImageFileChooser(); imageFileChooser.setMultiSelectionEnabled(false); } int returnVal = imageFileChooser.showOpenDialog(DesignerContext.getDesignerFrame()); - if (returnVal != JFileChooser.CANCEL_OPTION) { - File selectedFile = imageFileChooser.getSelectedFile(); - - if (selectedFile != null && selectedFile.isFile()) { - String path = selectedFile.getPath(); - suffix = ImageIOHelper.getSuffix(path); - Image image = BaseUtils.readImage(path); - CoreGraphHelper.waitForImage(image); - - previewPane.setImage(image); - imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(imageLayoutPane.getSelectedItem()); - previewPane.setImageStyle(imageStyle); - previewPane.repaint(); - } else { - previewPane.setImage(null); - } - fireChagneListener(); - } - + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(imageLayoutPane.getSelectedItem()); + ImgChooseWrapper.getInstance(previewPane, imageFileChooser, imageStyle, changeListener).dealWithImageFile(returnVal); } }; @@ -128,7 +108,7 @@ public class ImageBackgroundQuickPane extends BackgroundQuickPane { Style.DEFAULT_STYLE.deriveImageLayout(imageBackground.getLayout()); previewPane.setImageStyle(ImageBackgroundQuickPane.this.imageStyle); - previewPane.setImage(imageBackground.getImage()); + previewPane.setImageWithSuffix(imageBackground.getImageWithSuffix()); previewPane.repaint(); } diff --git a/designer-base/src/com/fr/design/mainframe/backgroundpane/ImagePreviewPane.java b/designer-base/src/com/fr/design/mainframe/backgroundpane/ImagePreviewPane.java index 1a170ce4b..a97699ff6 100644 --- a/designer-base/src/com/fr/design/mainframe/backgroundpane/ImagePreviewPane.java +++ b/designer-base/src/com/fr/design/mainframe/backgroundpane/ImagePreviewPane.java @@ -4,285 +4,311 @@ package com.fr.design.mainframe.backgroundpane; * Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved. */ -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.List; +import com.fr.base.BaseUtils; +import com.fr.base.GraphHelper; +import com.fr.base.Style; +import com.fr.design.constants.UIConstants; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.iscrollbar.UIScrollBar; +import com.fr.design.style.background.image.ImagePreviewer; +import com.fr.general.ImageWithSuffix; +import com.fr.general.Inter; +import com.fr.stable.Constants; +import com.fr.stable.CoreGraphHelper; import javax.swing.BorderFactory; import javax.swing.JComponent; - -import com.fr.design.constants.UIConstants; -import com.fr.design.gui.ilable.UILabel; import javax.swing.JPanel; import javax.swing.JViewport; import javax.swing.Scrollable; import javax.swing.SwingConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; - -import com.fr.base.BaseUtils; -import com.fr.base.GraphHelper; -import com.fr.base.Style; -import com.fr.design.gui.iscrollbar.UIScrollBar; -import com.fr.stable.Constants; -import com.fr.stable.CoreGraphHelper; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; /** * The pane use to preview image */ -public class ImagePreviewPane extends JComponent implements Scrollable { +public class ImagePreviewPane extends JComponent implements Scrollable, ImagePreviewer { private static final int LABEL_DELTA_X = 10; private static final int LABEL_DELTA_Y = 20; private static final int LABEL_HEIGHT = 20; private static final int INCRE_DELTA = 10; - private Image image = null; - // carl:image style - private Style imageStyle = null; - private int imageWidth = 0; - private int imageHeight = 0; + private ImageWithSuffix image = null; + // carl:image style + private Style imageStyle = null; + private int imageWidth = 0; + private int imageHeight = 0; + + private List changeListenerList = new ArrayList(); + private UILabel sizeLabel; + private boolean isLoading = false; + + public ImagePreviewPane() { + sizeLabel = new UILabel(); + this.add(sizeLabel); + this.setBorder(BorderFactory.createEmptyBorder(10, 10, 20, 10)); + this.setLayout(new BorderLayout()); + this.add(new JPanel() { + public void paintComponent(Graphics g) { + super.paintComponent(g); + if (isLoading) { + g.drawString(Inter.getLocText("FR-Designer_Image_Loading"), getWidth() / 2 - 25, getHeight() / 2); + return; + } + // draw image. + if (getImage() != null) { + // carl:让imagePreviewPane能预览样式 + if (getImageStyle() == null) { + g.drawImage(getImage(), 0, 0, this); + } else { + if (getImage().getWidth(this) > getWidth() || getImage().getHeight(this) > getHeight()) { + GraphHelper.paintImageMoved(g, this.getWidth(), this.getHeight(), getImage(), Constants.IMAGE_ADJUST, BaseUtils.getAlignment4Horizontal(getImageStyle()), + getImageStyle().getVerticalAlignment(), -1, -1, 0, 0, false, UIConstants.NORMAL_BACKGROUND); + } else { + int totalwidth = this.getWidth(); + int totalheight = this.getHeight(); + g.drawImage(getImage(), totalwidth / 2 - imageWidth / 2, totalheight / 2 - imageHeight / 2, this); + } + } + } + } + }, BorderLayout.CENTER); + // this.setToolTipText("View Image"); + } + + /** + * Return image + */ + public Image getImage() { + return image == null ? null : this.image.getImage(); + } + + /** + * Return ImageWithSuffix + */ + public ImageWithSuffix getImageWithSuffix() { + return this.image; + } - private List changeListenerList = new ArrayList(); - private UILabel sizeLabel; + /** + * Set image. + * + * @param image the new image. + */ + @Override + public void setImageWithSuffix(ImageWithSuffix image) { + this.image = image; + // need to reset the size of JViewPort. + if (this.image == null) { + if (this.getParent() instanceof JViewport) { + UIScrollBar tmpJScrollBar = new UIScrollBar(UIScrollBar.HORIZONTAL); + Dimension newDimension = new Dimension(this.getSize().width - tmpJScrollBar.getPreferredSize().height, this.getSize().height + - tmpJScrollBar.getPreferredSize().height); + ((JViewport) this.getParent()).setPreferredSize(newDimension); + (this.getParent()).setSize(newDimension); + ((JViewport) this.getParent()).setMinimumSize(newDimension); + ((JViewport) this.getParent()).setMaximumSize(newDimension); + } + sizeLabel.setText(null); + } else { + isLoading = false; + // wait for the size of image. + CoreGraphHelper.waitForImage(image); - public ImagePreviewPane() { - sizeLabel = new UILabel(); - this.add(sizeLabel); - this.setBorder(BorderFactory.createEmptyBorder(10, 10, 20, 10)); - this.setLayout(new BorderLayout()); - this.add(new JPanel() { - public void paintComponent(Graphics g) { - super.paintComponent(g); + imageWidth = image.getWidth(null); + imageHeight = image.getHeight(null); + int totalwidth = ImagePreviewPane.this.getWidth(); + int totalheight = ImagePreviewPane.this.getHeight(); + String text = imageWidth + "x" + imageHeight; + sizeLabel.setText(text); + FontMetrics cellFM = this.getFontMetrics(getFont()); + int width = cellFM.stringWidth(text); + sizeLabel.setBounds(totalwidth - width - LABEL_DELTA_X, totalheight - LABEL_DELTA_Y, width, LABEL_HEIGHT); + } + fireChangeListener(); + this.revalidate(); + } - // draw image. - if (getImage() != null) { - // carl:让imagePreviewPane能预览样式 - if (getImageStyle() == null) { - g.drawImage(getImage(), 0, 0, this); - } else { - if (getImage().getWidth(this) > getWidth() || getImage().getHeight(this) > getHeight()) { - GraphHelper.paintImageMoved(g, this.getWidth(), this.getHeight(), getImage(), Constants.IMAGE_ADJUST, BaseUtils.getAlignment4Horizontal(getImageStyle()), - getImageStyle().getVerticalAlignment(), -1, -1,0, 0, false, UIConstants.NORMAL_BACKGROUND); - } else { - int totalwidth = this.getWidth(); - int totalheight = this.getHeight(); - g.drawImage(getImage(), totalwidth / 2 - imageWidth / 2, totalheight / 2 - imageHeight / 2, this); - } - } - } - } - }, BorderLayout.CENTER); - // this.setToolTipText("View Image"); - } + @Override + public void showLoading() { + isLoading = true; + setImage(null); + repaint(); + } - /** - * Return image - */ - public Image getImage() { - return this.image; - } + /** + * Paint component. + */ - /** - * Set image. - * - * @param image - * the new image. - */ - public void setImage(Image image) { - this.image = image; - // need to reset the size of JViewPort. - if (this.image == null) { - if (this.getParent() instanceof JViewport) { - UIScrollBar tmpJScrollBar = new UIScrollBar(UIScrollBar.HORIZONTAL); - Dimension newDimension = new Dimension(this.getSize().width - tmpJScrollBar.getPreferredSize().height, this.getSize().height - - tmpJScrollBar.getPreferredSize().height); - ((JViewport)this.getParent()).setPreferredSize(newDimension); - (this.getParent()).setSize(newDimension); - ((JViewport)this.getParent()).setMinimumSize(newDimension); - ((JViewport)this.getParent()).setMaximumSize(newDimension); - } - sizeLabel.setText(null); - } else { - // wait for the size of image. - CoreGraphHelper.waitForImage(image); + @Override + public Dimension getPreferredSize() { + if (this.image == null) { + return super.getPreferredSize(); + } - imageWidth = image.getWidth(null); - imageHeight = image.getHeight(null); - int totalwidth = ImagePreviewPane.this.getWidth(); - int totalheight = ImagePreviewPane.this.getHeight(); - String text = imageWidth + "x" + imageHeight; - sizeLabel.setText(text); - FontMetrics cellFM = this.getFontMetrics(getFont()); - int width = cellFM.stringWidth(text); - sizeLabel.setBounds(totalwidth - width - LABEL_DELTA_X, totalheight - LABEL_DELTA_Y, width, LABEL_HEIGHT); - } - fireChangeListener(); - this.revalidate(); - } + return new Dimension(imageWidth, imageHeight); + } - /** - * Paint component. - */ + /** + * Add change listener. + */ + public void addChangeListener(ChangeListener changeListener) { + changeListenerList.add(changeListener); + } - public Dimension getPreferredSize() { - if (this.image == null) { - return super.getPreferredSize(); - } + /** + * fire change listener when image changed. + */ + private void fireChangeListener() { + if (this.changeListenerList.size() > 0) { + ChangeEvent evt = new ChangeEvent(this); - return new Dimension(imageWidth, imageHeight); - } + for (int i = 0; i < changeListenerList.size(); i++) { + changeListenerList.get(i).stateChanged(evt); + } + } + } - /** - * Add change listener. - */ - public void addChangeListener(ChangeListener changeListener) { - changeListenerList.add(changeListener); - } + // --- Scrollable methods --------------------------------------------- - /** - * fire change listener when image changed. - */ - private void fireChangeListener() { - if (this.changeListenerList.size() > 0) { - ChangeEvent evt = new ChangeEvent(this); + /** + * Returns the preferred size of the viewport for a view component. This is + * implemented to do the default behavior of returning the preferred size of + * the component. + * + * @return the preferredSize of a JViewport whose + * view is this Scrollable + */ + @Override + public Dimension getPreferredScrollableViewportSize() { + return getPreferredSize(); + } - for (int i = 0; i < changeListenerList.size(); i++) { - changeListenerList.get(i).stateChanged(evt); - } - } - } + /** + * Components that display logical rows or columns should compute the scroll + * increment that will completely expose one new row or column, depending on + * the value of orientation. Ideally, components should handle a partially + * exposed row or column by returning the distance required to completely + * expose the item. + *

+ * The default implementation of this is to simply return 10% of the visible + * area. Subclasses are likely to be able to provide a much more reasonable + * value. + * + * @param visibleRect the view area visible within the viewport + * @param orientation either SwingConstants.VERTICAL or + * SwingConstants.HORIZONTAL + * @param direction less than zero to scroll up/left, greater than zero for + * down/right + * @return the "unit" increment for scrolling in the specified direction + * @throws IllegalArgumentException for an invalid orientation + * @see javax.swing.JScrollBar#setUnitIncrement + */ + @Override + public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { + switch (orientation) { + case SwingConstants.VERTICAL: + return visibleRect.height / INCRE_DELTA; + case SwingConstants.HORIZONTAL: + return visibleRect.width / INCRE_DELTA; + default: + throw new IllegalArgumentException("Invalid orientation: " + orientation); + } + } - // --- Scrollable methods --------------------------------------------- + /** + * Components that display logical rows or columns should compute the scroll + * increment that will completely expose one block of rows or columns, + * depending on the value of orientation. + *

+ * The default implementation of this is to simply return the visible area. + * Subclasses will likely be able to provide a much more reasonable value. + * + * @param visibleRect the view area visible within the viewport + * @param orientation either SwingConstants.VERTICAL or + * SwingConstants.HORIZONTAL + * @param direction less than zero to scroll up/left, greater than zero for + * down/right + * @return the "block" increment for scrolling in the specified direction + * @throws IllegalArgumentException for an invalid orientation + * @see javax.swing.JScrollBar#setBlockIncrement + */ + @Override + public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { + switch (orientation) { + case SwingConstants.VERTICAL: + return visibleRect.height; + case SwingConstants.HORIZONTAL: + return visibleRect.width; + default: + throw new IllegalArgumentException("Invalid orientation: " + orientation); + } + } - /** - * Returns the preferred size of the viewport for a view component. This is - * implemented to do the default behavior of returning the preferred size of - * the component. - * - * @return the preferredSize of a JViewport whose - * view is this Scrollable - */ - public Dimension getPreferredScrollableViewportSize() { - return getPreferredSize(); - } + /** + * Returns true if a viewport should always force the width of this + * Scrollable to match the width of the viewport. For example a + * normal text view that supported line wrapping would return true here, + * since it would be undesirable for wrapped lines to disappear beyond the + * right edge of the viewport. Note that returning true for a + * Scrollable whose ancestor is a JScrollPane + * effectively disables horizontal scrolling. + *

+ * Scrolling containers, like JViewport, will use this method + * each time they are validated. + * + * @return true if a viewport should force the Scrollables + * width to match its own + */ + @Override + public boolean getScrollableTracksViewportWidth() { + if (getParent() instanceof JViewport) { + return (getParent().getWidth() > getPreferredSize().width); + } + return false; + } - /** - * Components that display logical rows or columns should compute the scroll - * increment that will completely expose one new row or column, depending on - * the value of orientation. Ideally, components should handle a partially - * exposed row or column by returning the distance required to completely - * expose the item. - *

- * The default implementation of this is to simply return 10% of the visible - * area. Subclasses are likely to be able to provide a much more reasonable - * value. - * - * @param visibleRect - * the view area visible within the viewport - * @param orientation - * either SwingConstants.VERTICAL or - * SwingConstants.HORIZONTAL - * @param direction - * less than zero to scroll up/left, greater than zero for - * down/right - * @return the "unit" increment for scrolling in the specified direction - * @throws IllegalArgumentException - * for an invalid orientation - * @see javax.swing.JScrollBar#setUnitIncrement - */ - public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { - switch (orientation) { - case SwingConstants.VERTICAL: - return visibleRect.height / INCRE_DELTA; - case SwingConstants.HORIZONTAL: - return visibleRect.width / INCRE_DELTA; - default: - throw new IllegalArgumentException("Invalid orientation: " + orientation); - } - } + /** + * Returns true if a viewport should always force the height of this + * Scrollable to match the height of the viewport. For example + * a columnar text view that flowed text in left to right columns could + * effectively disable vertical scrolling by returning true here. + *

+ * Scrolling containers, like JViewport, will use this method + * each time they are validated. + * + * @return true if a viewport should force the Scrollables height to match + * its own + */ + @Override + public boolean getScrollableTracksViewportHeight() { + if (getParent() instanceof JViewport) { + return (getParent().getHeight() > getPreferredSize().height); + } + return false; + } - /** - * Components that display logical rows or columns should compute the scroll - * increment that will completely expose one block of rows or columns, - * depending on the value of orientation. - *

- * The default implementation of this is to simply return the visible area. - * Subclasses will likely be able to provide a much more reasonable value. - * - * @param visibleRect - * the view area visible within the viewport - * @param orientation - * either SwingConstants.VERTICAL or - * SwingConstants.HORIZONTAL - * @param direction - * less than zero to scroll up/left, greater than zero for - * down/right - * @return the "block" increment for scrolling in the specified direction - * @throws IllegalArgumentException - * for an invalid orientation - * @see javax.swing.JScrollBar#setBlockIncrement - */ - public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { - switch (orientation) { - case SwingConstants.VERTICAL: - return visibleRect.height; - case SwingConstants.HORIZONTAL: - return visibleRect.width; - default: - throw new IllegalArgumentException("Invalid orientation: " + orientation); - } - } + @Override + public void setImageStyle(Style imageStyle) { + this.imageStyle = imageStyle; + } - /** - * Returns true if a viewport should always force the width of this - * Scrollable to match the width of the viewport. For example a - * normal text view that supported line wrapping would return true here, - * since it would be undesirable for wrapped lines to disappear beyond the - * right edge of the viewport. Note that returning true for a - * Scrollable whose ancestor is a JScrollPane - * effectively disables horizontal scrolling. - *

- * Scrolling containers, like JViewport, will use this method - * each time they are validated. - * - * @return true if a viewport should force the Scrollables - * width to match its own - */ - public boolean getScrollableTracksViewportWidth() { - if (getParent() instanceof JViewport) { - return (getParent().getWidth() > getPreferredSize().width); - } - return false; - } + @Override + public void setImage(Image image) { - /** - * Returns true if a viewport should always force the height of this - * Scrollable to match the height of the viewport. For example - * a columnar text view that flowed text in left to right columns could - * effectively disable vertical scrolling by returning true here. - *

- * Scrolling containers, like JViewport, will use this method - * each time they are validated. - * - * @return true if a viewport should force the Scrollables height to match - * its own - */ - public boolean getScrollableTracksViewportHeight() { - if (getParent() instanceof JViewport) { - return (getParent().getHeight() > getPreferredSize().height); - } - return false; - } + setImageWithSuffix(image == null ? null : new ImageWithSuffix(image)); - public void setImageStyle(Style imageStyle) { - this.imageStyle = imageStyle; - } + } - public Style getImageStyle() { - return imageStyle; - } + public Style getImageStyle() { + return imageStyle; + } } \ No newline at end of file diff --git a/designer-base/src/com/fr/design/style/background/image/ExpandFileChooser.java b/designer-base/src/com/fr/design/style/background/image/ExpandFileChooser.java new file mode 100644 index 000000000..b9690b243 --- /dev/null +++ b/designer-base/src/com/fr/design/style/background/image/ExpandFileChooser.java @@ -0,0 +1,196 @@ +package com.fr.design.style.background.image; + +import com.fr.base.BaseUtils; +import com.fr.design.DesignerEnvManager; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.Inter; +import com.fr.stable.StringUtils; + +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JPanel; +import javax.swing.plaf.metal.MetalFileChooserUI; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.event.ActionListener; + +/** + * 扩展的文件选择框(底部控制区域扩展一个复选框) + * Created by zack on 2018/3/8. + */ +public class ExpandFileChooser extends JFileChooser { + private JDialog dialog; + private UICheckBox checkBox;//选择框底部的复选按钮 + private int retVal = ERROR_OPTION; + private UIButton approve; + private UIButton cancel; + private static final int DEFAULT_WIDTH = 520; + + public ExpandFileChooser() { + this(StringUtils.EMPTY, StringUtils.EMPTY); + } + + public ExpandFileChooser(String checkBoxText, String approveButtonText) { + JPanel previewContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + MetalFileChooserUI chooserUI = (MetalFileChooserUI) getUI(); + String approveText = StringUtils.isEmpty(approveButtonText) ? chooserUI.getApproveButtonText(this) : approveButtonText; + dialog = new JDialog(); + + dialog.setSize(new Dimension(DEFAULT_WIDTH, 362)); + dialog.add(previewContainerPane); + dialog.setIconImage(BaseUtils.readImage("/com/fr/base/images/oem/logo.png")); + dialog.setTitle(approveText); + previewContainerPane.add(this, BorderLayout.CENTER); + + + JPanel bottomControlPanel = new JPanel(); + bottomControlPanel.setLayout(new ImageAreaLayout()); + bottomControlPanel.setPreferredSize(new Dimension(DEFAULT_WIDTH, 40)); + + approve = new UIButton(approveText); + cancel = new UIButton(Inter.getLocText("FR-Designer_Button-Cancel")); + if (StringUtils.isNotEmpty(checkBoxText)) { + checkBox = new UICheckBox(checkBoxText); + checkBox.setSelected(DesignerEnvManager.getEnvManager().isImageCompress()); + bottomControlPanel.add(checkBox); + checkBox.addActionListener(checkAction()); + } + bottomControlPanel.add(approve); + approve.addActionListener(chooserUI.getApproveSelectionAction()); + cancel.addActionListener(chooserUI.getCancelSelectionAction()); + bottomControlPanel.add(cancel); + previewContainerPane.add(bottomControlPanel, BorderLayout.SOUTH); + GUICoreUtils.centerWindow(dialog); + } + + public ActionListener checkAction() { + return null; + } + + public boolean isCheckSelected() { + if (checkBox != null) { + return checkBox.isSelected(); + } + return false; + } + + + @Override + public int showDialog(Component parent, String approveButtonText) { + dialog.setModal(true); + dialog.setVisible(true); + return retVal; + } + + @Override + public void approveSelection() { + retVal = APPROVE_OPTION; + if (dialog != null) { + dialog.setVisible(false); + } + fireActionPerformed(APPROVE_SELECTION); + } + + @Override + public void cancelSelection() { + retVal = CANCEL_OPTION; + if (dialog != null) { + dialog.setVisible(false); + } + fireActionPerformed(CANCEL_SELECTION); + } + + @Override + public boolean getControlButtonsAreShown() { + return false;//隐藏默认的控制按钮(打开/取消) + } + + private class ImageAreaLayout implements LayoutManager { + private static final int TEN = 10; + private int hGap = 5; + private int topMargin = TEN; + private int leftMargin = TEN; + private int leftStart = 8; + + @Override + public void addLayoutComponent(String string, Component comp) { + } + + @Override + public void layoutContainer(Container container) { + Component[] children = container.getComponents(); + + if (children != null && children.length > 0) { + int numChildren = children.length; + Dimension[] sizes = new Dimension[numChildren]; + Insets insets = container.getInsets(); + int yLocation = insets.top + topMargin; + int maxWidth = 0; + + for (int counter = 0; counter < numChildren; counter++) { + sizes[counter] = children[counter].getPreferredSize(); + maxWidth = Math.max(maxWidth, sizes[counter].width); + } + int xLocation, xOffset; + if (container.getComponentOrientation().isLeftToRight()) { + xLocation = container.getSize().width - insets.left - maxWidth - leftMargin; + xOffset = hGap + maxWidth; + } else { + xLocation = insets.left; + xOffset = -(hGap + maxWidth); + } + //单独设置图片压缩按钮的位置 + children[0].setBounds(leftStart, yLocation, + maxWidth, sizes[0].height); + + for (int counter = numChildren - 1; counter >= 1; counter--) { + children[counter].setBounds(xLocation, yLocation, + maxWidth, sizes[counter].height); + xLocation -= xOffset; + } + } + } + + @Override + public Dimension minimumLayoutSize(Container c) { + if (c != null) { + Component[] children = c.getComponents(); + + if (children != null && children.length > 0) { + int numChildren = children.length; + int height = 0; + Insets cInsets = c.getInsets(); + int extraHeight = topMargin + cInsets.top + cInsets.bottom; + int extraWidth = cInsets.left + cInsets.right; + int maxWidth = 0; + + for (int counter = 0; counter < numChildren; counter++) { + Dimension aSize = children[counter].getPreferredSize(); + height = Math.max(height, aSize.height); + maxWidth = Math.max(maxWidth, aSize.width); + } + return new Dimension(extraWidth + numChildren * maxWidth + + (numChildren - 1) * hGap, + extraHeight + height); + } + } + return new Dimension(0, 0); + } + + @Override + public Dimension preferredLayoutSize(Container c) { + return minimumLayoutSize(c); + } + + @Override + public void removeLayoutComponent(Component c) { + } + } +} diff --git a/designer-base/src/com/fr/design/style/background/image/ImageFileChooser.java b/designer-base/src/com/fr/design/style/background/image/ImageFileChooser.java index e5fbb3bad..10fb9a061 100644 --- a/designer-base/src/com/fr/design/style/background/image/ImageFileChooser.java +++ b/designer-base/src/com/fr/design/style/background/image/ImageFileChooser.java @@ -3,25 +3,27 @@ */ package com.fr.design.style.background.image; +import com.fr.base.BaseUtils; +import com.fr.design.DesignerEnvManager; +import com.fr.design.style.ChooseFileView; +import com.fr.general.Inter; + +import javax.swing.filechooser.FileFilter; import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.io.File; import java.util.Enumeration; import java.util.Hashtable; -import javax.swing.JFileChooser; -import javax.swing.filechooser.FileFilter; - -import com.fr.base.BaseUtils; -import com.fr.general.Inter; -import com.fr.design.style.ChooseFileView; - /** * This class used to choose image files. */ -public class ImageFileChooser extends JFileChooser { +public class ImageFileChooser extends ExpandFileChooser { public ImageFileChooser() { + super(Inter.getLocText("FR-Designer_Image_Compress"),Inter.getLocText("FR-Designer_Open")); ExampleFileFilter bothFilter = new ExampleFileFilter( new String[]{"jpg", "gif", "png", "bmp"}, Inter.getLocText("Image-Image_Files")); @@ -43,12 +45,23 @@ public class ImageFileChooser extends JFileChooser { return super.showDialog(parent, approveButtonText); } + @Override + public ActionListener checkAction() { + return new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + DesignerEnvManager.getEnvManager().setImageCompress(isCheckSelected()); + DesignerEnvManager.getEnvManager().saveXMLFile(); + } + }; + + } /** * A convenience implementation of FileFilter that filters out * all files except for those type extensions that it knows about. *

D:\finereport\develop\code\test\TestCase\WEB-INF\reportlets\TestCase\01903.cpt - + *

* Extensions are of the type ".foo", which is typically found on * Windows and Unix boxes, but not on Macinthosh. Case is ignored. *

diff --git a/designer-base/src/com/fr/design/style/background/image/ImagePreviewPane.java b/designer-base/src/com/fr/design/style/background/image/ImagePreviewPane.java index 35c5a5d3f..296686f24 100644 --- a/designer-base/src/com/fr/design/style/background/image/ImagePreviewPane.java +++ b/designer-base/src/com/fr/design/style/background/image/ImagePreviewPane.java @@ -3,12 +3,13 @@ */ package com.fr.design.style.background.image; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.List; +import com.fr.base.BaseUtils; +import com.fr.base.GraphHelper; +import com.fr.base.Style; +import com.fr.design.gui.iscrollbar.UIScrollBar; +import com.fr.general.ImageWithSuffix; +import com.fr.general.Inter; +import com.fr.stable.CoreGraphHelper; import javax.swing.JComponent; import javax.swing.JViewport; @@ -16,46 +17,67 @@ import javax.swing.Scrollable; import javax.swing.SwingConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; - -import com.fr.base.BaseUtils; -import com.fr.base.GraphHelper; -import com.fr.base.Style; -import com.fr.design.gui.iscrollbar.UIScrollBar; -import com.fr.stable.CoreGraphHelper; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; /** * The pane use to preview image */ -public class ImagePreviewPane extends JComponent implements Scrollable { - private Image image = null; +public class ImagePreviewPane extends JComponent implements Scrollable, ImagePreviewer { + private ImageWithSuffix image = null; // carl:image style private Style imageStyle = null; - private int imageWidth = 0 ; - private int imageHeight = 0 ; + private int imageWidth = 0; + private int imageHeight = 0; + private boolean isLoading = false; private List changeListenerList = new ArrayList(); public ImagePreviewPane() { - this.setToolTipText("View Image"); + this.setToolTipText("View Image"); } /** * Return image */ public Image getImage() { + return image == null ? null : image.getImage(); + } + /** + * Return image + */ + public ImageWithSuffix getImageWithSuffix() { return this.image; } + public void showLoading() { + isLoading = true; + setImage(null); + repaint(); + } + + @Override + public void setImage(Image image) { + + setImageWithSuffix(image == null ? null : new ImageWithSuffix(image)); + + } + /** * Set image. * * @param image the new image. */ - public void setImage(Image image) { + @Override + public void setImageWithSuffix(ImageWithSuffix image) { this.image = image; //need to reset the size of JViewPort. if (this.image == null) { - if(this.getParent() instanceof JViewport) { + if (this.getParent() instanceof JViewport) { UIScrollBar tmpJScrollBar = new UIScrollBar(UIScrollBar.HORIZONTAL); Dimension newDimension = new Dimension( this.getSize().width - tmpJScrollBar.getPreferredSize().height, @@ -67,6 +89,7 @@ public class ImagePreviewPane extends JComponent implements Scrollable { } } else { //wait for the size of image. + isLoading = false; CoreGraphHelper.waitForImage(image); imageWidth = image.getWidth(null); @@ -81,25 +104,29 @@ public class ImagePreviewPane extends JComponent implements Scrollable { /** * Paint component. */ + @Override public void paintComponent(Graphics g) { super.paintComponent(g); - - //draw image. - if (this.getImage() != null) { - // carl:让imagePreviewPane能预览样式 - if (this.getImageStyle() == null) { - g.drawImage(this.getImage(), 0, 0, this); - } else { - GraphHelper.paintImage( - g, this.getWidth(), this.getHeight(), this.getImage(), - this.getImageStyle().getImageLayout(), - BaseUtils.getAlignment4Horizontal(this.getImageStyle()), - this.getImageStyle().getVerticalAlignment(), -1, -1 - ); - } + if (isLoading) { + g.drawString(Inter.getLocText("FR-Designer_Image_Loading"), getWidth() / 2 - 25, getHeight() / 2); + return; + } + if (this.getImage() != null) { //draw image. + // carl:让imagePreviewPane能预览样式 + if (this.getImageStyle() == null) { + g.drawImage(this.getImage(), 0, 0, this); + } else { + GraphHelper.paintImage( + g, this.getWidth(), this.getHeight(), this.getImage(), + this.getImageStyle().getImageLayout(), + BaseUtils.getAlignment4Horizontal(this.getImageStyle()), + this.getImageStyle().getVerticalAlignment(), -1, -1 + ); + } } } + @Override public Dimension getPreferredSize() { if (this.image == null) { return super.getPreferredSize(); @@ -123,7 +150,7 @@ public class ImagePreviewPane extends JComponent implements Scrollable { ChangeEvent evt = new ChangeEvent(this); for (int i = 0; i < changeListenerList.size(); i++) { - changeListenerList.get(i).stateChanged(evt); + changeListenerList.get(i).stateChanged(evt); } } } @@ -136,8 +163,9 @@ public class ImagePreviewPane extends JComponent implements Scrollable { * the preferred size of the component. * * @return the preferredSize of a JViewport - * whose view is this Scrollable + * whose view is this Scrollable */ + @Override public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } @@ -192,6 +220,7 @@ public class ImagePreviewPane extends JComponent implements Scrollable { * @throws IllegalArgumentException for an invalid orientation * @see javax.swing.JScrollBar#setBlockIncrement */ + @Override public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { switch (orientation) { case SwingConstants.VERTICAL: @@ -218,8 +247,9 @@ public class ImagePreviewPane extends JComponent implements Scrollable { * will use this method each time they are validated. * * @return true if a viewport should force the Scrollables - * width to match its own + * width to match its own */ + @Override public boolean getScrollableTracksViewportWidth() { if (getParent() instanceof JViewport) { return (getParent().getWidth() > getPreferredSize().width); @@ -238,8 +268,9 @@ public class ImagePreviewPane extends JComponent implements Scrollable { * will use this method each time they are validated. * * @return true if a viewport should force the Scrollables height - * to match its own + * to match its own */ + @Override public boolean getScrollableTracksViewportHeight() { if (getParent() instanceof JViewport) { return (getParent().getHeight() > getPreferredSize().height); @@ -247,11 +278,12 @@ public class ImagePreviewPane extends JComponent implements Scrollable { return false; } - public void setImageStyle(Style imageStyle) { - this.imageStyle = imageStyle; - } + @Override + public void setImageStyle(Style imageStyle) { + this.imageStyle = imageStyle; + } - public Style getImageStyle() { - return imageStyle; - } + public Style getImageStyle() { + return imageStyle; + } } \ No newline at end of file diff --git a/designer-base/src/com/fr/design/style/background/image/ImagePreviewer.java b/designer-base/src/com/fr/design/style/background/image/ImagePreviewer.java new file mode 100644 index 000000000..58fe65bcf --- /dev/null +++ b/designer-base/src/com/fr/design/style/background/image/ImagePreviewer.java @@ -0,0 +1,40 @@ +package com.fr.design.style.background.image; + +import com.fr.base.Style; +import com.fr.general.ImageWithSuffix; + +import java.awt.Image; + +/** + * 图片预览接口(由于子类上层父类差别较大,无奈的接口) + * Created by zack on 2018/3/10. + */ +public interface ImagePreviewer { + /** + * 设置图片样式(平铺,拉伸) + * @param style 样式 + */ + void setImageStyle(Style style); + + /** + * 设置图片 + * @param image 图片 + */ + void setImage(Image image); + + /** + * 设置图片(带格式) + * @param image 图片 + */ + void setImageWithSuffix(ImageWithSuffix image); + + /** + * 显示正在加载 + */ + void showLoading(); + + /** + * 重绘 + */ + void repaint(); +} diff --git a/designer-base/src/com/fr/design/style/background/image/ImageSelectPane.java b/designer-base/src/com/fr/design/style/background/image/ImageSelectPane.java index 7c2def75b..77c4c9bb8 100644 --- a/designer-base/src/com/fr/design/style/background/image/ImageSelectPane.java +++ b/designer-base/src/com/fr/design/style/background/image/ImageSelectPane.java @@ -1,9 +1,9 @@ package com.fr.design.style.background.image; -import com.fr.base.BaseUtils; import com.fr.base.background.ImageFileBackground; import com.fr.base.frpx.pack.PictureCollection; import com.fr.base.frpx.util.ImageIOHelper; +import com.fr.design.gui.frpane.ImgChooseWrapper; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.ilable.UILabel; @@ -13,7 +13,6 @@ import com.fr.design.style.background.BackgroundPane4BoxChange; import com.fr.general.Background; import com.fr.general.Inter; import com.fr.stable.Constants; -import com.fr.stable.CoreGraphHelper; import javax.swing.JFileChooser; import javax.swing.JPanel; @@ -100,20 +99,13 @@ public class ImageSelectPane extends BackgroundPane4BoxChange { } ActionListener selectPictureActionListener = new ActionListener() { - - @Override public void actionPerformed(ActionEvent evt) { int returnVal = imageFileChooser.showOpenDialog(ImageSelectPane.this); if (returnVal != JFileChooser.CANCEL_OPTION) { File selectedFile = imageFileChooser.getSelectedFile(); - if (selectedFile != null && selectedFile.isFile()) { - String path = selectedFile.getPath(); - suffix = ImageIOHelper.getSuffix(path); - Image image = BaseUtils.readImage(path); - CoreGraphHelper.waitForImage(image); - selectImage = image; - } - chechLabelText(); + String path = selectedFile.getPath(); + suffix = ImageIOHelper.getSuffix(path); + ImgChooseWrapper.getInstance(selectImage, imageSizeLabel, imageFileChooser).dealWithImageFile(returnVal); } } }; diff --git a/designer-base/src/com/fr/design/style/background/impl/ImageBackgroundPane.java b/designer-base/src/com/fr/design/style/background/impl/ImageBackgroundPane.java index c9643a6a3..cd35373bf 100644 --- a/designer-base/src/com/fr/design/style/background/impl/ImageBackgroundPane.java +++ b/designer-base/src/com/fr/design/style/background/impl/ImageBackgroundPane.java @@ -1,10 +1,8 @@ package com.fr.design.style.background.impl; -import com.fr.base.BaseUtils; import com.fr.base.Style; -import com.fr.base.background.ImageFileBackground; -import com.fr.base.frpx.pack.PictureCollection; -import com.fr.base.frpx.util.ImageIOHelper; +import com.fr.base.background.ImageBackground; +import com.fr.design.gui.frpane.ImgChooseWrapper; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UIRadioButton; import com.fr.design.gui.ilable.UILabel; @@ -15,11 +13,9 @@ import com.fr.design.style.background.image.ImagePreviewPane; import com.fr.general.Background; import com.fr.general.Inter; import com.fr.stable.Constants; -import com.fr.stable.CoreGraphHelper; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; -import javax.swing.JFileChooser; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.event.ChangeEvent; @@ -29,7 +25,6 @@ import java.awt.GridLayout; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.io.File; /** * Image background pane. @@ -47,8 +42,6 @@ public class ImageBackgroundPane extends BackgroundDetailPane { private UIRadioButton extendRadioButton = null; private UIRadioButton adjustRadioButton = null; - private String suffix = PictureCollection.DEFAULT_SUFFIX; - public ImageBackgroundPane() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); @@ -124,36 +117,14 @@ public class ImageBackgroundPane extends BackgroundDetailPane { */ ActionListener selectPictureActionListener = new ActionListener() { - @Override public void actionPerformed(ActionEvent evt) { int returnVal = imageFileChooser.showOpenDialog(ImageBackgroundPane.this); - if (returnVal != JFileChooser.CANCEL_OPTION) { - File selectedFile = imageFileChooser.getSelectedFile(); - - if (selectedFile != null && selectedFile.isFile()) { - String path = selectedFile.getPath(); - suffix = ImageIOHelper.getSuffix(path); - Image image = BaseUtils.readImage(path); - CoreGraphHelper.waitForImage(image); - - previewPane.setImage(image); - imageStyleRepaint(); - previewPane.repaint(); - } else { - previewPane.setImage(null); - } - } - - fireChagneListener(); + setImageStyle(); + ImgChooseWrapper.getInstance(previewPane, imageFileChooser, imageStyle, changeListener).dealWithImageFile(returnVal); } }; - public void imageStyleRepaint() { - setImageStyle(); - previewPane.setImageStyle(imageStyle); - } - - private void setImageStyle() { + protected void setImageStyle() { if (tiledRadioButton.isSelected()) { imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_TILED); } else if (adjustRadioButton.isSelected()) { @@ -182,9 +153,8 @@ public class ImageBackgroundPane extends BackgroundDetailPane { @Override public void populate(Background background) { - if (background instanceof ImageFileBackground) { - ImageFileBackground imageBackground = (ImageFileBackground) background; - suffix = imageBackground.getSuffix(); + if (background instanceof ImageBackground) { + ImageBackground imageBackground = (ImageBackground) background; if (imageBackground.getLayout() == Constants.IMAGE_CENTER) { defaultRadioButton.setSelected(true); @@ -202,7 +172,7 @@ public class ImageBackgroundPane extends BackgroundDetailPane { previewPane.setImageStyle(ImageBackgroundPane.this.imageStyle); if (imageBackground.getImage() != null) { - previewPane.setImage(imageBackground.getImage()); + previewPane.setImageWithSuffix(imageBackground.getImageWithSuffix()); imageSizeLabel.setText(previewPane.getImage().getWidth(null) + " X " + previewPane.getImage().getHeight(null)); } @@ -222,7 +192,7 @@ public class ImageBackgroundPane extends BackgroundDetailPane { @Override public Background update() throws Exception { - ImageFileBackground imageBackground = new ImageFileBackground(previewPane.getImage(), suffix); + ImageBackground imageBackground = new ImageBackground(previewPane.getImageWithSuffix()); setImageStyle(); imageBackground.setLayout(imageStyle.getImageLayout()); return imageBackground; @@ -253,12 +223,4 @@ public class ImageBackgroundPane extends BackgroundDetailPane { } } }; - - public String getSuffix() { - return suffix; - } - - public void setSuffix(String suffix) { - this.suffix = suffix; - } } diff --git a/designer-base/src/com/fr/design/style/background/impl/ImageBackgroundPane4Browser.java b/designer-base/src/com/fr/design/style/background/impl/ImageBackgroundPane4Browser.java index 431ad2c0d..537d03e57 100644 --- a/designer-base/src/com/fr/design/style/background/impl/ImageBackgroundPane4Browser.java +++ b/designer-base/src/com/fr/design/style/background/impl/ImageBackgroundPane4Browser.java @@ -1,10 +1,5 @@ package com.fr.design.style.background.impl; -import com.fr.design.gui.ibutton.UIRadioButton; -import com.fr.stable.ArrayUtils; - -import javax.swing.*; - /** * Created by richie on 16/5/18. */ @@ -15,12 +10,4 @@ public class ImageBackgroundPane4Browser extends ImageBackgroundPane { super(); } - @Override - protected UIRadioButton[] imageLayoutButtons() { - - return (UIRadioButton[]) ArrayUtils.addAll(super.imageLayoutButtons(), new UIRadioButton[] { - defaultRadioButton, - tiledRadioButton, - }); - } } diff --git a/designer-base/src/com/fr/design/style/background/impl/ImageButtonBackgroundPane.java b/designer-base/src/com/fr/design/style/background/impl/ImageButtonBackgroundPane.java index 1464a4e9f..3e8540a3c 100644 --- a/designer-base/src/com/fr/design/style/background/impl/ImageButtonBackgroundPane.java +++ b/designer-base/src/com/fr/design/style/background/impl/ImageButtonBackgroundPane.java @@ -1,15 +1,16 @@ package com.fr.design.style.background.impl; import com.fr.base.Style; -import com.fr.base.background.ImageFileBackground; -import com.fr.base.frpx.pack.PictureCollection; +import com.fr.base.background.ImageBackground; import com.fr.design.gui.ibutton.UIButton; import com.fr.general.Background; import com.fr.general.Inter; import com.fr.stable.Constants; -import javax.swing.*; -import java.awt.*; +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -55,24 +56,21 @@ public class ImageButtonBackgroundPane extends ImageBackgroundPane { public void actionPerformed(ActionEvent e) { previewPane.setImage(null); previewPane.repaint(); - setSuffix(PictureCollection.DEFAULT_SUFFIX); } }); } @Override - public void imageStyleRepaint() { - + public void setImageStyle() { } @Override public void populate(Background background) { - if (background instanceof ImageFileBackground) { - ImageFileBackground imageBackground = (ImageFileBackground) background; - setSuffix(imageBackground.getSuffix()); + if (background != null && background instanceof ImageBackground) { + ImageBackground imageBackground = (ImageBackground) background; if (imageBackground.getImage() != null) { - previewPane.setImage(imageBackground.getImage()); + previewPane.setImageWithSuffix(imageBackground.getImageWithSuffix()); } } @@ -83,6 +81,6 @@ public class ImageButtonBackgroundPane extends ImageBackgroundPane { if (previewPane.getImage() == null) { return null; } - return new ImageFileBackground(previewPane.getImage(), getSuffix()); + return new ImageBackground(previewPane.getImageWithSuffix()); } } diff --git a/designer-base/src/com/fr/design/utils/ImageUtils.java b/designer-base/src/com/fr/design/utils/ImageUtils.java new file mode 100644 index 000000000..33f928a46 --- /dev/null +++ b/designer-base/src/com/fr/design/utils/ImageUtils.java @@ -0,0 +1,285 @@ +package com.fr.design.utils; + +import com.fr.base.BaseUtils; +import com.fr.general.ComparatorUtils; +import com.fr.general.FRLogger; +import com.fr.general.ImageWithSuffix; +import com.fr.stable.CoreGraphHelper; +import com.fr.stable.StringUtils; + +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.ImageOutputStream; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Transparency; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.Iterator; + +/** + * 设计器部分的图片处理工具类 + * Created by zack on 2018/3/8. + */ +public class ImageUtils { + public static final String TYPE_JPEG = "JPEG"; + public static final String TYPE_PNG = "png"; + + /** + * 默认压缩算法,采用75%质量压缩,带透明度的png默认使用缩放的方式实现压缩尺寸压缩50%,大小大约为1/4 + * + * @param imageFile 原文件 + * @return 压缩后的BufferedImage对象 + */ + public static Image defaultImageCompress(File imageFile) { + if (imageFile == null || !imageFile.exists()) { + return null; + } + try { + BufferedImage srcImg = BaseUtils.readImage(imageFile.getPath()); + if (canbeCompressedToJPEG(imageFile)) { + return jpegCompress(srcImg, 0.75f); + } else if (isPNGType(imageFile)) { + //带透明度的采用缩放的方式 + return scale(srcImg, 0.5f, true); + } + } catch (IOException e) { + FRLogger.getLogger().info("image compress failed!"); + + } + return BaseUtils.readImage(imageFile.getPath()); + } + + /** + * 默认压缩算法,返回带格式的image + * + * @param imageFile 原文件 + * @return 压缩后的BufferedImage对象 + */ + public static ImageWithSuffix defaultImageCompWithSuff(File imageFile) { + if (imageFile == null || !imageFile.exists()) { + return null; + } + BufferedImage srcImg = BaseUtils.readImage(imageFile.getPath()); + Image desImg = srcImg; + try { + + if (canbeCompressedToJPEG(imageFile)) { + return new ImageWithSuffix(jpegCompress(srcImg, 0.75f), TYPE_JPEG); + } else if (isPNGType(imageFile)) { + //带透明度的采用缩放的方式 + desImg = scale(srcImg, 0.5f, true); + } + } catch (IOException e) { + FRLogger.getLogger().info("image compress failed!"); + + } + return new ImageWithSuffix(desImg, TYPE_PNG); + } + + public static boolean canbeCompressedToJPEG(File imageFile) { + String imageType = getImageType(imageFile); + if (ComparatorUtils.equals(imageType, TYPE_JPEG)) {//JPEG大写 + return true; + } + if (ComparatorUtils.equals(imageType, TYPE_PNG)) {//png小写 + return !isAlphaAreaOverload(imageFile);//少量透明度系数的png直接压缩jpg + } + return false; + } + + /** + * 判断图片是否是png类型 + * + * @param imageFile + * @return + */ + public static boolean isPNGType(File imageFile) { + if (ComparatorUtils.equals(getImageType(imageFile), TYPE_PNG)) { + return true; + } + return false; + } + + /** + * JPEG格式图片压缩 + * + * @param image 压缩源图片 + * @param quality 压缩质量,在0-1之间, + * @return 返回的字节数组 + */ + public static BufferedImage jpegCompress(BufferedImage image, float quality) throws IOException { + if (image == null) { + return null; + } + // 得到指定Format图片的writer + Iterator iter = ImageIO + .getImageWritersByFormatName("jpeg");// 得到迭代器 + ImageWriter writer = iter.next(); + + // 得到指定writer的输出参数设置(ImageWriteParam ) + ImageWriteParam iwp = writer.getDefaultWriteParam(); + iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 设置可否压缩 + iwp.setCompressionQuality(quality); // 设置压缩质量参数 + iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED); + + // 开始打包图片,写入byte[] + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream ios = null; + ByteArrayInputStream in = null; + try { + image = copy(image, BufferedImage.TYPE_INT_RGB); + ios = ImageIO.createImageOutputStream(byteArrayOutputStream); + writer.setOutput(ios); + writer.write(null, new IIOImage(image, null, null), iwp); + in = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); + if (ios == null || in == null) { + throw new IOException("The image file cannot be compressed"); + } + return ImageIO.read(in); + } finally { + writer.dispose(); + byteArrayOutputStream.close(); + if (ios != null) { + ios.close(); + } + if (in != null) { + in.close(); + } + } + } + + /** + * 判断图片中是否包含多于5%的透明区域,这个5%随便定的 + * + * @param imageFile 目标图片 + * @return 含透明度像素占比 + */ + public static boolean isAlphaAreaOverload(File imageFile) { + if (imageFile == null || !imageFile.isFile()) { + return false; + } + BufferedImage bufferedImage = BaseUtils.readImage(imageFile.getPath()); + int width = bufferedImage.getWidth(); + int height = bufferedImage.getHeight(); + long alphaCount = 0; + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + int rgb = bufferedImage.getRGB(i, j); + int a = (0xff & (rgb >> 24)); + if (a != 0xff) { + alphaCount++; + } + } + } + return alphaCount / (double) (width * height) > 0.05; + } + + /** + * 获取图片类型 + * + * @param imageFile 图片文件 + * @return 图片类型(JPEG, PNG, GIF) + */ + public static String getImageType(File imageFile) { + try { + ImageInputStream iis = ImageIO.createImageInputStream(imageFile); + Iterator iter = ImageIO.getImageReaders(iis); + if (!iter.hasNext()) { + return StringUtils.EMPTY; + } + ImageReader reader = iter.next(); + iis.close(); + return reader.getFormatName(); + } catch (IOException ignore) { + } + return StringUtils.EMPTY; + } + + private static BufferedImage copy(BufferedImage img, int imageType) { + int width = img.getWidth(); + int height = img.getHeight(); + + BufferedImage newImage = CoreGraphHelper.createBufferedImage(width, height, imageType); + Graphics g = newImage.createGraphics(); + + g.drawImage(img, 0, 0, null); + + g.dispose(); + + return newImage; + } + + /** + * 缩放图像(按比例缩放) + * + * @param srcImg 源图像来源流 + * @param scale 缩放比例。比例大于1时为放大,小于1大于0为缩小 + * @param opacityCompatible 是否处理背景透明 + */ + public static Image scale(BufferedImage srcImg, float scale, boolean opacityCompatible) { + if (scale < 0) { + // 自动修正负数 + scale = -scale; + } + + int width = mul(Integer.toString(srcImg.getWidth(null)), Float.toString(scale)).intValue(); // 得到源图宽 + int height = mul(Integer.toString(srcImg.getHeight(null)), Float.toString(scale)).intValue(); // 得到源图长 + return scale(srcImg, width, height, opacityCompatible); + } + + private static BigDecimal mul(String v1, String v2) { + return mul(new BigDecimal(v1), new BigDecimal(v2)); + } + + private static BigDecimal mul(BigDecimal v1, BigDecimal v2) { + return v1.multiply(v2); + } + + /** + * 缩放图像(按长宽缩放) + * 目标长宽与原图不成比例会变形 + * + * @param srcImg 源图像来源流 + * @param width 目标宽度 + * @param height 目标高度 + * @param opacityCompatible 是否处理背景透明 + * @return {@link Image} + */ + private static Image scale(BufferedImage srcImg, int width, int height, boolean opacityCompatible) { + int srcHeight = srcImg.getHeight(null); + int srcWidth = srcImg.getWidth(null); + int scaleType; + if (srcHeight == height && srcWidth == width) { + // 源与目标长宽一致返回原图 + return srcImg; + } else if (srcHeight < height || srcWidth < width) { + // 放大图片使用平滑模式 + scaleType = Image.SCALE_SMOOTH; + } else { + scaleType = Image.SCALE_DEFAULT; + } + if (opacityCompatible) {//需要保留透明度背景 + BufferedImage toImg = CoreGraphHelper.createBufferedImage(width, height, srcImg.getType()); + Graphics2D g2d = toImg.createGraphics(); + toImg = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT); + g2d.dispose(); + + g2d = toImg.createGraphics(); + Image from = srcImg.getScaledInstance(width, height, scaleType); + g2d.drawImage(from, 0, 0, null); + g2d.dispose(); + return toImg; + } + return srcImg.getScaledInstance(width, height, scaleType); + } +} diff --git a/designer-realize/src/com/fr/design/headerfooter/ImagePane.java b/designer-realize/src/com/fr/design/headerfooter/ImagePane.java index b018c2d57..2ccdc10fa 100644 --- a/designer-realize/src/com/fr/design/headerfooter/ImagePane.java +++ b/designer-realize/src/com/fr/design/headerfooter/ImagePane.java @@ -3,25 +3,22 @@ */ package com.fr.design.headerfooter; -import java.awt.BorderLayout; -import java.awt.Image; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; - -import javax.swing.BorderFactory; -import javax.swing.JFileChooser; -import javax.swing.JPanel; -import javax.swing.JScrollPane; - -import com.fr.base.BaseUtils; +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.frpane.ImgChooseWrapper; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.dialog.BasicPane; -import com.fr.general.Inter; -import com.fr.stable.CoreGraphHelper; import com.fr.design.style.background.image.ImageFileChooser; import com.fr.design.style.background.image.ImagePreviewPane; +import com.fr.general.Inter; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingWorker; +import java.awt.BorderLayout; +import java.awt.Image; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; /** * Image Pane. @@ -67,17 +64,17 @@ public class ImagePane extends BasicPane { imageFileChooser = new ImageFileChooser(); imageFileChooser.setMultiSelectionEnabled(false); } - + @Override protected String title4PopupWindow() { - return "image"; + return "image"; } public void populate(Image image) { - if(image == null) { - return; - } - + if(image == null) { + return; + } + this.imagePreviewPane.setImage(image); } @@ -91,19 +88,7 @@ public class ImagePane extends BasicPane { ActionListener selectPictureActionListener = new ActionListener() { public void actionPerformed(ActionEvent evt) { int returnVal = imageFileChooser.showOpenDialog(ImagePane.this); - if (returnVal != JFileChooser.CANCEL_OPTION) { - File selectedFile = imageFileChooser.getSelectedFile(); - - if (selectedFile != null && selectedFile.isFile()) { - Image image = BaseUtils.readImage(selectedFile.getPath()); - CoreGraphHelper.waitForImage(image); - - imagePreviewPane.setImage(image); - } else { - imagePreviewPane.setImage(null); - } - imagePreviewPane.repaint(); - } + ImgChooseWrapper.getInstance(imagePreviewPane, imageFileChooser, null).dealWithImageFile(returnVal); } }; } \ No newline at end of file From e356bfb4874149c13ba32789d79e163cef3fceec Mon Sep 17 00:00:00 2001 From: plough Date: Thu, 7 Jun 2018 16:40:41 +0800 Subject: [PATCH 3/9] =?UTF-8?q?REPORT-8355=209.0=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E7=9A=84=E5=8A=9F=E8=83=BD=E4=B8=8Ebug=20pat?= =?UTF-8?q?ch=E5=88=B010.0=EF=BC=88=E9=83=A8=E5=88=86=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/design/ExtraDesignClassManager.java | 114 +++-- .../designer/properties/items/Item.java | 4 +- .../design/fun/CellWidgetOptionProvider.java | 7 + .../controlpane/UISimpleListControlPane.java | 483 ++++++++++++++++++ .../widget/mobile/WidgetMobilePane.java | 47 ++ .../design/designer/creator/XElementCase.java | 8 + .../mainframe/FormEditorKeyListener.java | 46 +- .../mainframe/MobileWidgetListPane.java | 71 +++ .../fr/design/widget/CellWidgetCardPane.java | 74 ++- .../widget/WidgetMobilePaneFactory.java | 39 ++ .../ui/mobile/MultiFileEditorMobilePane.java | 84 +++ 11 files changed, 883 insertions(+), 94 deletions(-) rename {designer-form => designer-base}/src/com/fr/design/designer/properties/items/Item.java (92%) create mode 100644 designer-base/src/com/fr/design/gui/controlpane/UISimpleListControlPane.java create mode 100644 designer-base/src/com/fr/design/widget/mobile/WidgetMobilePane.java create mode 100644 designer-form/src/com/fr/design/mainframe/MobileWidgetListPane.java create mode 100644 designer-realize/src/com/fr/design/widget/WidgetMobilePaneFactory.java create mode 100644 designer-realize/src/com/fr/design/widget/ui/mobile/MultiFileEditorMobilePane.java diff --git a/designer-base/src/com/fr/design/ExtraDesignClassManager.java b/designer-base/src/com/fr/design/ExtraDesignClassManager.java index 179251539..bfef815c8 100644 --- a/designer-base/src/com/fr/design/ExtraDesignClassManager.java +++ b/designer-base/src/com/fr/design/ExtraDesignClassManager.java @@ -17,10 +17,11 @@ import com.fr.design.gui.core.WidgetOption; import com.fr.design.gui.core.WidgetOptionFactory; import com.fr.design.menu.ShortCut; import com.fr.design.widget.Appearance; +import com.fr.design.widget.mobile.WidgetMobilePane; import com.fr.form.ui.Widget; +import com.fr.general.FRLogger; import com.fr.general.GeneralUtils; import com.fr.general.IOUtils; -import com.fr.log.FineLoggerFactory; import com.fr.plugin.AbstractExtraClassManager; import com.fr.plugin.injectable.PluginModule; import com.fr.plugin.injectable.PluginSingleInjection; @@ -41,24 +42,24 @@ import java.util.Set; * 用于设计器扩展的管理类 */ public class ExtraDesignClassManager extends AbstractExtraClassManager implements ExtraDesignClassManagerProvider { - + private static ExtraDesignClassManager classManager = new ExtraDesignClassManager(); - + private Set shortCuts = new CloseableContainedSet<>(HashSet.class); - + public synchronized static ExtraDesignClassManager getInstance() { return classManager; } - + static { PluginModule.registerAgent(PluginModule.ExtraDesign, classManager); } - + public TableDataNameObjectCreator[] getReportTableDataCreators() { return getKindsOfTableDataCreators(TableDataDefineProvider.XML_TAG); } - - + + /** * 添加serverTDCreators * @@ -67,7 +68,7 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement public TableDataNameObjectCreator[] getServerTableDataCreators() { return getKindsOfTableDataCreators(ServerTableDataDefineProvider.XML_TAG); } - + private TableDataNameObjectCreator[] getKindsOfTableDataCreators(String tag) { Set set = getArray(tag); if (set.isEmpty()) { @@ -76,19 +77,19 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement List creators = new ArrayList<>(); for (TableDataDefineProvider provider : set) { TableDataNameObjectCreator creator = new TableDataNameObjectCreator( - provider.nameForTableData(), - provider.prefixForTableData(), - provider.iconPathForTableData(), - provider.classForTableData(), - provider.classForInitTableData(), - provider.appearanceForTableData() + provider.nameForTableData(), + provider.prefixForTableData(), + provider.iconPathForTableData(), + provider.classForTableData(), + provider.classForInitTableData(), + provider.appearanceForTableData() ); creators.add(creator); } return creators.toArray(new TableDataNameObjectCreator[creators.size()]); } - - + + public Map, Class> getParameterWidgetOptionsMap() { Map, Class> map = new HashMap<>(); Set set = getArray(ParameterWidgetOptionProvider.XML_TAG); @@ -97,7 +98,7 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement } return map; } - + public WidgetOption[] getParameterWidgetOptions() { Set set = getArray(ParameterWidgetOptionProvider.XML_TAG); if (set.isEmpty()) { @@ -106,16 +107,16 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement Set result = new HashSet<>(); for (ParameterWidgetOptionProvider provider : set) { WidgetOption option = WidgetOptionFactory.createByWidgetClass( - provider.nameForWidget(), - IOUtils.readIcon(provider.iconPathForWidget()), - provider.classForWidget() + provider.nameForWidget(), + IOUtils.readIcon(provider.iconPathForWidget()), + provider.classForWidget() ); result.add(option); } return result.toArray(new WidgetOption[result.size()]); } - - + + public WidgetOption[] getWebWidgetOptions() { Set set = getArray(ToolbarItemProvider.XML_TAG); if (set.isEmpty()) { @@ -124,17 +125,17 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement List list = new ArrayList<>(); for (ToolbarItemProvider provider : set) { WidgetOption option = WidgetOptionFactory.createByWidgetClass( - provider.nameForWidget(), - IOUtils.readIcon(provider.iconPathForWidget()), - provider.classForWidget() + provider.nameForWidget(), + IOUtils.readIcon(provider.iconPathForWidget()), + provider.classForWidget() ); list.add(option); } return list.toArray(new WidgetOption[list.size()]); } - - - + + + public Map, Class> getFormWidgetOptionsMap() { Set set = getArray(FormWidgetOptionProvider.XML_TAG); Map, Class> map = new HashMap<>(); @@ -143,15 +144,15 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement } return map; } - + public WidgetOption[] getFormWidgetOptions() { return getFormUnits(false); } - + public WidgetOption[] getFormWidgetContainerOptions() { return getFormUnits(true); } - + private WidgetOption[] getFormUnits(boolean isContainer) { Set set = getArray(FormWidgetOptionProvider.XML_TAG); if (set.isEmpty()) { @@ -161,18 +162,18 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement for (FormWidgetOptionProvider provider : set) { if (provider.isContainer() == isContainer) { WidgetOption option = WidgetOptionFactory.createByWidgetClass( - provider.nameForWidget(), - BaseUtils.readIcon(provider.iconPathForWidget()), - provider.classForWidget() + provider.nameForWidget(), + BaseUtils.readIcon(provider.iconPathForWidget()), + provider.classForWidget() ); result.add(option); } } return result.toArray(new WidgetOption[result.size()]); } - - - + + + public WidgetOption[] getCellWidgetOptions() { Set set = getArray(CellWidgetOptionProvider.XML_TAG); if (set.isEmpty()) { @@ -181,16 +182,16 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement Set result = new HashSet<>(); for (CellWidgetOptionProvider provider : set) { WidgetOption option = WidgetOptionFactory.createByWidgetClass( - provider.nameForWidget(), - IOUtils.readIcon(provider.iconPathForWidget()), - provider.classForWidget() + provider.nameForWidget(), + IOUtils.readIcon(provider.iconPathForWidget()), + provider.classForWidget() ); result.add(option); } return result.toArray(new WidgetOption[result.size()]); - + } - + public Map, Appearance> getCellWidgetOptionsMap() { Set set = getArray(CellWidgetOptionProvider.XML_TAG); Map, Appearance> map = new HashMap<>(); @@ -199,8 +200,17 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement } return map; } - - + + public Map, Class> getCellWidgetMobileOptionsMap() { + Set set = getArray(CellWidgetOptionProvider.XML_TAG); + Map, Class> map = new HashMap<>(); + for (CellWidgetOptionProvider provider : set) { + map.put(provider.classForWidget(), provider.classForMobilePane()); + } + return map; + } + + public Feedback getFeedback() { try { Class clazz = GeneralUtils.classForName("com.fr.design.feedback.CurrentFeedback"); @@ -208,33 +218,33 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement return (Feedback) clazz.newInstance(); } } catch (Exception e) { - FineLoggerFactory.getLogger().info("no feed back support"); + FRLogger.getLogger().info("no feed back support"); } return Feedback.EMPTY; } - + @Override protected boolean demountSpecific(PluginSingleInjection injection) { - + if (ShortCut.TEMPLATE_TREE.equals(injection.getName()) && injection.getObject() instanceof ShortCut) { shortCuts.remove(injection.getObject()); return true; } return false; } - + @Override protected boolean mountSpecific(PluginSingleInjection injection) { - + if (ShortCut.TEMPLATE_TREE.equals(injection.getName()) && injection.getObject() instanceof ShortCut) { shortCuts.add((ShortCut) injection.getObject()); return true; } return false; } - + public Set getExtraShortCuts() { - + return Collections.unmodifiableSet(shortCuts); } } \ No newline at end of file diff --git a/designer-form/src/com/fr/design/designer/properties/items/Item.java b/designer-base/src/com/fr/design/designer/properties/items/Item.java similarity index 92% rename from designer-form/src/com/fr/design/designer/properties/items/Item.java rename to designer-base/src/com/fr/design/designer/properties/items/Item.java index 31ae4a070..6cba90e41 100644 --- a/designer-form/src/com/fr/design/designer/properties/items/Item.java +++ b/designer-base/src/com/fr/design/designer/properties/items/Item.java @@ -24,7 +24,7 @@ public class Item { } @Override - public boolean equals(Object o) { + public boolean equals(Object o) { if (o == null) { return false; } @@ -32,7 +32,7 @@ public class Item { Item a = (Item) o; Object av = a.getValue(); if (value == null) { - return av == null; + return av == null; } else { if (av == null) { return false; diff --git a/designer-base/src/com/fr/design/fun/CellWidgetOptionProvider.java b/designer-base/src/com/fr/design/fun/CellWidgetOptionProvider.java index 1cb7869d7..e22b68146 100644 --- a/designer-base/src/com/fr/design/fun/CellWidgetOptionProvider.java +++ b/designer-base/src/com/fr/design/fun/CellWidgetOptionProvider.java @@ -1,6 +1,7 @@ package com.fr.design.fun; import com.fr.design.beans.BasicBeanPane; +import com.fr.design.widget.mobile.WidgetMobilePane; import com.fr.form.ui.Widget; import com.fr.stable.fun.Level; @@ -20,4 +21,10 @@ public interface CellWidgetOptionProvider extends ParameterWidgetOptionProvider */ Class> appearanceForWidget(); + /** + * 自定义格子控件的移动端界面类 + * @return 控件移动端界面类 + */ + Class classForMobilePane(); + } \ No newline at end of file diff --git a/designer-base/src/com/fr/design/gui/controlpane/UISimpleListControlPane.java b/designer-base/src/com/fr/design/gui/controlpane/UISimpleListControlPane.java new file mode 100644 index 000000000..a07e4c2ce --- /dev/null +++ b/designer-base/src/com/fr/design/gui/controlpane/UISimpleListControlPane.java @@ -0,0 +1,483 @@ +package com.fr.design.gui.controlpane; + +import com.fr.base.BaseUtils; +import com.fr.design.actions.UpdateAction; +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.ilist.ListModelElement; +import com.fr.design.gui.ilist.UIList; +import com.fr.design.gui.itoolbar.UIToolBarUI; +import com.fr.design.gui.itoolbar.UIToolbar; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.menu.ShortCut; +import com.fr.design.menu.ToolBarDef; +import com.fr.general.ComparatorUtils; +import com.fr.general.Inter; +import com.fr.stable.ArrayUtils; +import com.fr.stable.Nameable; +import com.fr.stable.StringUtils; +import sun.swing.DefaultLookup; + +import javax.swing.BorderFactory; +import javax.swing.DefaultListModel; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; +import javax.swing.ListSelectionModel; +import javax.swing.border.Border; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.Arrays; +import java.util.Comparator; + +/** + * 简单列表面板 + * Created by plough on 2018/2/1. + */ +public class UISimpleListControlPane extends BasicPane { + public static final String LIST_NAME = "UISimpleControl_List"; + + protected UIList nameList; + protected String selectedName; + private ShortCut4JControlPane[] shorts; + private ToolBarDef toolbarDef; + private UIToolbar toolBar; + + public UISimpleListControlPane() { + initComponentPane(); + } + + public ShortCut4JControlPane[] getShorts() { + return shorts; + } + + protected void initComponentPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.add(getContentPane(), BorderLayout.CENTER); + this.checkButtonEnabled(); + } + + protected JPanel getContentPane() { + JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + JPanel listPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + initListPane(listPane); + contentPane.add(listPane, BorderLayout.CENTER); + + shorts = this.createShortcuts(); + if (ArrayUtils.isEmpty(shorts)) { + return contentPane; + } + + toolbarDef = new ToolBarDef(); + for (ShortCut4JControlPane sj : shorts) { + toolbarDef.addShortCut(sj.getShortCut()); + } + toolBar = ToolBarDef.createJToolBar(); + toolBar.setUI(new UIToolBarUI(){ + @Override + public void paint(Graphics g, JComponent c) { + Graphics2D g2 = (Graphics2D) g; + g2.setColor(Color.WHITE); + g2.fillRect(0, 0, c.getWidth(), c.getHeight()); + } + }); + toolbarDef.updateToolBar(toolBar); + // 封装一层,加边框 + JPanel toolBarPane = new JPanel(new BorderLayout()); + toolBarPane.add(toolBar, BorderLayout.CENTER); + toolBarPane.setBorder(BorderFactory.createMatteBorder(1, 1, 0, 1, UIConstants.RULER_LINE_COLOR)); + + listPane.add(toolBarPane, BorderLayout.NORTH); + + return contentPane; + } + + protected ShortCut4JControlPane[] createShortcuts() { + return new ShortCut4JControlPane[]{ + moveUpItemShortCut(), + moveDownItemShortCut(), + sortItemShortCut(), + }; + } + + protected void initListPane(JPanel listPane) { + nameList = createJNameList(); + nameList.setName(LIST_NAME); + nameList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS); + listPane.add(new UIScrollPane(nameList), BorderLayout.CENTER); + + + nameList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + nameList.addMouseListener(listMouseListener); + nameList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent evt) { + // richie:避免多次update和populate大大降低效率 + if (!evt.getValueIsAdjusting()) { + UISimpleListControlPane.this.checkButtonEnabled(); + } + } + }); + } + + public UIList createJNameList() { + UIList nameList = new UIList(new DefaultListModel()) { + @Override + public int locationToIndex(Point location) { + int index = super.locationToIndex(location); + if (index != -1 && !getCellBounds(index, index).contains(location)) { + return -1; + } + else { + return index; + } + } + }; + nameList.setCellRenderer(new NameableListCellRenderer(this)); + return nameList; + } + + protected ShortCut4JControlPane moveUpItemShortCut() { + return new NormalEnableShortCut(new MoveUpItemAction()); + } + + protected ShortCut4JControlPane moveDownItemShortCut() { + return new NormalEnableShortCut(new MoveDownItemAction()); + } + + protected ShortCut4JControlPane sortItemShortCut() { + return new NormalEnableShortCut(new SortItemAction()); + } + + public Nameable[] update() { + java.util.List res = new java.util.ArrayList(); + DefaultListModel listModel = (DefaultListModel) this.nameList.getModel(); + for (int i = 0, len = listModel.getSize(); i < len; i++) { + res.add(((ListModelElement) listModel.getElementAt(i)).wrapper); + } + + return res.toArray(new Nameable[res.size()]); + } + + public void populate(Nameable[] nameableArray) { + DefaultListModel listModel = (DefaultListModel) this.nameList.getModel(); + listModel.removeAllElements(); + if (ArrayUtils.isEmpty(nameableArray)) { + return; + } + + listModel.setSize(nameableArray.length); + for (int i = 0; i < nameableArray.length; i++) { + listModel.set(i, new ListModelElement(nameableArray[i])); + } + if (listModel.size() > 0 || this.nameList.getSelectedIndex() != 0) { + this.nameList.setSelectedIndex(0); + } + this.checkButtonEnabled(); + } + + /** + * 根据name,选中UINameEdList中的item + */ + public void setSelectedName(String name) { + DefaultListModel listModel = (DefaultListModel) this.nameList.getModel(); + for (int i = 0, len = listModel.getSize(); i < len; i++) { + Nameable item = ((ListModelElement) listModel.getElementAt(i)).wrapper; + if (ComparatorUtils.equals(name, item.getName())) { + this.nameList.setSelectedIndex(i); + break; + } + } + } + + /** + * 获取选中的名字 + */ + public String getSelectedName() { + ListModelElement el = (ListModelElement) this.nameList.getSelectedValue(); + + return el == null ? null : el.wrapper.getName(); + } + + protected DefaultListModel getModel() { + return (DefaultListModel) this.nameList.getModel(); + } + + @Override + protected String title4PopupWindow() { + return null; + } + + /* + * 上移Item + */ + private class MoveUpItemAction extends UpdateAction { + public MoveUpItemAction() { + this.setName(Inter.getLocText("Utils-Move_Up")); + this.setMnemonic('U'); + this.setSmallIcon(BaseUtils + .readIcon("/com/fr/design/images/control/up.png")); + } + + @Override + public void actionPerformed(ActionEvent evt) { + int selectedIndex = nameList.getSelectedIndex(); + if (selectedIndex == -1) { + return; + } + + // 上移 + if (selectedIndex > 0) { + DefaultListModel listModel = (DefaultListModel) nameList.getModel(); + + Object prevObj = listModel.get(selectedIndex - 1); + Object currentObj = listModel.get(selectedIndex); + listModel.set(selectedIndex - 1, currentObj); + listModel.set(selectedIndex, prevObj); + + nameList.setSelectedIndex(selectedIndex - 1); + nameList.ensureIndexIsVisible(selectedIndex - 1); + } + } + } + + /* + * 下移Item + */ + private class MoveDownItemAction extends UpdateAction { + public MoveDownItemAction() { + this.setName(Inter.getLocText("Utils-Move_Down")); + this.setMnemonic('D'); + this.setSmallIcon(BaseUtils + .readIcon("/com/fr/design/images/control/down.png")); + } + + @Override + public void actionPerformed(ActionEvent evt) { + int selectedIndex = nameList.getSelectedIndex(); + if (selectedIndex == -1) { + return; + } + + if (selectedIndex < nameList.getModel().getSize() - 1) { + DefaultListModel listModel = (DefaultListModel) nameList.getModel(); + + Object nextObj = listModel.get(selectedIndex + 1); + Object currentObj = listModel.get(selectedIndex); + listModel.set(selectedIndex + 1, currentObj); + listModel.set(selectedIndex, nextObj); + + nameList.setSelectedIndex(selectedIndex + 1); + nameList.ensureIndexIsVisible(selectedIndex + 1); + } + } + } + + private class SortItemAction extends UpdateAction { + private boolean isAtoZ = false; + + public SortItemAction() { + this.setName(Inter.getLocText("FR-Action_Sort")); + this.setMnemonic('S'); + this.setSmallIcon(BaseUtils + .readIcon("/com/fr/design/images/control/sortAsc.png")); + } + + @Override + public void actionPerformed(ActionEvent evt) { + // p:选中的值. + Object selectedValue = nameList.getSelectedValue(); + + DefaultListModel listModel = (DefaultListModel) nameList.getModel(); + if (listModel.getSize() <= 0) { + return; + } + Nameable[] nameableArray = new Nameable[listModel.getSize()]; + + for (int i = 0; i < listModel.getSize(); i++) { + nameableArray[i] = ((ListModelElement) listModel.getElementAt(i)).wrapper; + } + + // p:排序. + if (isAtoZ) { // 升序 + Comparator nameableComparator = new Comparator() { + @Override + public int compare(Nameable o1, Nameable o2) { + return ComparatorUtils.compare(o2.getName(), o1.getName()); + } + }; + isAtoZ = !isAtoZ; + Arrays.sort(nameableArray, nameableComparator); + } else { // 降序 + Comparator nameableComparator = new Comparator() { + @Override + public int compare(Nameable o1, Nameable o2) { + return ComparatorUtils.compare(o1.getName(), o2 + .getName()); + } + }; + isAtoZ = !isAtoZ; + Arrays.sort(nameableArray, nameableComparator); + } + + for (int i = 0; i < nameableArray.length; i++) { + listModel.set(i, new ListModelElement(nameableArray[i])); + } + + // p:需要选中以前的那个值. + if (selectedValue != null) { + nameList.setSelectedValue(selectedValue, true); + } + + checkButtonEnabled(); + // p:需要repaint. + nameList.repaint(); + } + } + + /* + * UIList的鼠标事件 + */ + private MouseListener listMouseListener = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + JList list = (JList) e.getSource(); + if (list.locationToIndex(e.getPoint()) == -1 && !e.isShiftDown() + && !isMenuShortcutKeyDown(e)) { + list.clearSelection(); + } + } + + private boolean isMenuShortcutKeyDown(InputEvent event) { + return (event.getModifiers() & Toolkit.getDefaultToolkit() + .getMenuShortcutKeyMask()) != 0; + } + }; + + /** + * 检查按钮可用状态 Check button enabled. + */ + public void checkButtonEnabled() { + for (ShortCut4JControlPane sj : getShorts()) { + sj.checkEnable(); + } + } + + /** + * 设置选中项 + * + * @param index 选中项的序列号 + */ + public void setSelectedIndex(int index) { + nameList.setSelectedIndex(index); + } + + + public class NormalEnableShortCut extends ShortCut4JControlPane { + public NormalEnableShortCut(ShortCut shortCut) { + this.shortCut = shortCut; + } + + /** + * 检查是否可用 + */ + @Override + public void checkEnable() { + this.shortCut.setEnabled(getModel() + .getSize() > 0 + && UISimpleListControlPane.this.nameList.getSelectedIndex() != -1); + } + } + + + private class NameableListCellRenderer extends + JPanel implements ListCellRenderer { + + private UILabel label; + private UISimpleListControlPane listControlPane; + private Color initialLabelForeground; + + public NameableListCellRenderer(UISimpleListControlPane listControlPane) { + super(); + this.listControlPane = listControlPane; + initComponents(); + setOpaque(true); + setBorder(getNoFocusBorder()); + setName("List.cellRenderer"); + } + + private void initComponents() { + label = new UILabel(); + label.setBorder(BorderFactory.createEmptyBorder(3, 10, 3, 0)); + initialLabelForeground = label.getForeground(); + this.setLayout(new BorderLayout()); + this.add(label, BorderLayout.CENTER); + } + + private Border getNoFocusBorder() { + return BorderFactory.createMatteBorder(0, 0, 1, 0, UIConstants.LIST_ITEM_SPLIT_LINE); + } + + private void setText(String t) { + label.setText(t); + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + setComponentOrientation(list.getComponentOrientation()); + + Color bg = null; + Color fg = null; + + JList.DropLocation dropLocation = list.getDropLocation(); + if (dropLocation != null + && !dropLocation.isInsert() + && dropLocation.getIndex() == index) { + + bg = DefaultLookup.getColor(this, ui, "List.dropCellBackground"); + fg = DefaultLookup.getColor(this, ui, "List.dropCellForeground"); + + isSelected = true; + } + + if (isSelected) { + setBackground(bg == null ? list.getSelectionBackground() : bg); + setForeground(fg == null ? list.getSelectionForeground() : fg); + label.setForeground(Color.WHITE); + } + else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + label.setForeground(initialLabelForeground); + } + + setText((value == null) ? StringUtils.EMPTY : value.toString()); + + setEnabled(list.isEnabled()); + setFont(list.getFont()); + + if (value instanceof ListModelElement) { + Nameable wrappee = ((ListModelElement) value).wrapper; + this.setText(wrappee.getName()); + } + + return this; + } + } +} diff --git a/designer-base/src/com/fr/design/widget/mobile/WidgetMobilePane.java b/designer-base/src/com/fr/design/widget/mobile/WidgetMobilePane.java new file mode 100644 index 000000000..392b4b500 --- /dev/null +++ b/designer-base/src/com/fr/design/widget/mobile/WidgetMobilePane.java @@ -0,0 +1,47 @@ +package com.fr.design.widget.mobile; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.form.ui.Widget; +import com.fr.general.Inter; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; + +/** + * 单元格控件的"移动端"面板。默认显示"无可用配置项",在子类中扩展 + * Created by plough on 2018/4/25. + */ +public class WidgetMobilePane extends JPanel { + public static WidgetMobilePane DEFAULT_PANE = new WidgetMobilePane(); + + public WidgetMobilePane() { + this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + init(); + } + + protected void init() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + UILabel label = new UILabel(Inter.getLocText("FR-Designer_No_Settings_Available")); + label.setHorizontalAlignment(SwingConstants.CENTER); + this.add(label); + } + + /** + * 从 widget 中提取数据展示在属性面板中 + * + * @param widget + */ + public void populate(Widget widget) { + // do nothing + } + + /** + * 从属性面板把数据保存到 widget 中 + * @param widget + */ + public void update(Widget widget) { + // do nothing + } +} diff --git a/designer-form/src/com/fr/design/designer/creator/XElementCase.java b/designer-form/src/com/fr/design/designer/creator/XElementCase.java index 0ca67aabf..05f301159 100644 --- a/designer-form/src/com/fr/design/designer/creator/XElementCase.java +++ b/designer-form/src/com/fr/design/designer/creator/XElementCase.java @@ -349,4 +349,12 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme public boolean supportSetEnable(){ return false; } + + /** + * 是否支持共享-现只支持报表块、图表、tab块、绝对布局 + * @return + */ + public boolean isSupportShared() { + return true; + } } \ No newline at end of file diff --git a/designer-form/src/com/fr/design/mainframe/FormEditorKeyListener.java b/designer-form/src/com/fr/design/mainframe/FormEditorKeyListener.java index 24d067d70..81f3d6efc 100644 --- a/designer-form/src/com/fr/design/mainframe/FormEditorKeyListener.java +++ b/designer-form/src/com/fr/design/mainframe/FormEditorKeyListener.java @@ -1,5 +1,10 @@ package com.fr.design.mainframe; +import com.fr.base.BaseUtils; +import com.fr.common.inputevent.InputEventBaseOnOS; +import java.awt.Cursor; +import java.awt.Point; +import java.awt.Toolkit; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -10,6 +15,9 @@ import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWAbsoluteLayout; public class FormEditorKeyListener extends KeyAdapter{ + private static final Cursor ADDCURSOR = Toolkit.getDefaultToolkit().createCustomCursor( + BaseUtils.readImage("/com/fr/design/images/form/designer/cursor/add.png"), new Point(0, 0), + "addCursor"); private FormDesigner designer; private boolean moved; @@ -19,6 +27,9 @@ public class FormEditorKeyListener extends KeyAdapter{ @Override public void keyPressed(KeyEvent e) { + if(e.isShiftDown() || InputEventBaseOnOS.isControlDown(e)) { + designer.setCursor(ADDCURSOR); + } int code = e.getKeyCode(); XCreator creator = designer.getSelectionModel().getSelection().getSelectedCreator(); XLayoutContainer container; @@ -26,26 +37,29 @@ public class FormEditorKeyListener extends KeyAdapter{ return; } moved = true; - + switch (code) { - case KeyEvent.VK_LEFT: - designer.getSelectionModel().move(-1, 0); - break; - case KeyEvent.VK_RIGHT: - designer.getSelectionModel().move(1, 0); - break; - case KeyEvent.VK_UP: - designer.getSelectionModel().move(0, -1); - break; - case KeyEvent.VK_DOWN: - designer.getSelectionModel().move(0, 1); - break; - default: - moved = false; + case KeyEvent.VK_LEFT: + designer.getSelectionModel().move(-1, 0); + break; + case KeyEvent.VK_RIGHT: + designer.getSelectionModel().move(1, 0); + break; + case KeyEvent.VK_UP: + designer.getSelectionModel().move(0, -1); + break; + case KeyEvent.VK_DOWN: + designer.getSelectionModel().move(0, 1); + break; + default: + moved = false; } } - + public void keyReleased(KeyEvent e) { + if(!(e.isShiftDown() || InputEventBaseOnOS.isControlDown(e))) { + designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } if (moved) { designer.getEditListenerTable().fireCreatorModified( designer.getSelectionModel().getSelection().getSelectedCreator(), DesignerEvent.CREATOR_RESIZED); diff --git a/designer-form/src/com/fr/design/mainframe/MobileWidgetListPane.java b/designer-form/src/com/fr/design/mainframe/MobileWidgetListPane.java new file mode 100644 index 000000000..40af6f34b --- /dev/null +++ b/designer-form/src/com/fr/design/mainframe/MobileWidgetListPane.java @@ -0,0 +1,71 @@ +package com.fr.design.mainframe; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.gui.controlpane.UISimpleListControlPane; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.WSortLayout; +import com.fr.general.NameObject; +import com.fr.stable.ArrayUtils; +import com.fr.stable.Nameable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by plough on 2018/1/31. + */ +public class MobileWidgetListPane extends UISimpleListControlPane { + public static final String LIST_NAME = "Widget_List"; + + private FormDesigner designer; + private WSortLayout wSortLayout; + private String[] widgetNameList; + + public MobileWidgetListPane(FormDesigner designer, WSortLayout wSortLayout) { + super(); + this.designer = designer; + this.wSortLayout = wSortLayout; + widgetNameList = getData(); + + List nameObjectList = new ArrayList(); + for (String name : widgetNameList) { + nameObjectList.add(new NameObject(name, null)); + } + populate(nameObjectList.toArray(new NameObject[nameObjectList.size()])); + } + + /** + * 保存移动端控件列表顺序 + */ + public void updateToDesigner() { + Nameable[] nameableList = update(); + List newMobileWidgetList = new ArrayList<>(); + for (Nameable nameable : nameableList) { + newMobileWidgetList.add(nameable.getName()); + } + wSortLayout.updateSortedMobileWidgetList(newMobileWidgetList); + } + + /** + * 获取选中控件的控件列表 + * + * @return List widgetNameList + */ + private String[] getData() { + //选择的控件 + XCreator selectedCreator = designer.getSelectionModel().getSelection().getSelectedCreator(); + Widget selectedModel = selectedCreator != null ? selectedCreator.toData() : null; + + if (selectedModel == null || !selectedModel.acceptType(WSortLayout.class)) { + return ArrayUtils.EMPTY_STRING_ARRAY; + } + + // 选择的控件有两种类型,一种是WLayout,代表容器,一种是Widget,代表控件 + List mobileWidgetList = ((WSortLayout) selectedModel).getOrderedMobileWidgetList(); + String[] widgetNames = new String[mobileWidgetList.size()]; + for (int i = 0; i < mobileWidgetList.size(); i++) { + widgetNames[i] = mobileWidgetList.get(i); + } + return widgetNames; + } +} \ No newline at end of file diff --git a/designer-realize/src/com/fr/design/widget/CellWidgetCardPane.java b/designer-realize/src/com/fr/design/widget/CellWidgetCardPane.java index 77d1542cb..c590a84b2 100644 --- a/designer-realize/src/com/fr/design/widget/CellWidgetCardPane.java +++ b/designer-realize/src/com/fr/design/widget/CellWidgetCardPane.java @@ -9,13 +9,16 @@ import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.ElementCasePane; +import com.fr.design.widget.mobile.WidgetMobilePane; import com.fr.design.widget.ui.BasicWidgetPropertySettingPane; import com.fr.form.event.Listener; import com.fr.form.ui.Widget; import com.fr.general.Inter; -import javax.swing.*; -import java.awt.*; +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.CardLayout; import java.util.ArrayList; /* @@ -24,6 +27,8 @@ import java.util.ArrayList; public class CellWidgetCardPane extends BasicPane { //当前的编辑器属性定义面板 private DataModify currentEditorDefinePane; + //当前的编辑器移动端面板 + private WidgetMobilePane currentWidgetMobilePane; //属性配置切换面板 private ArrayList paneList; private JPanel center; @@ -40,6 +45,11 @@ public class CellWidgetCardPane extends BasicPane { private JPanel eventTabPane; private WidgetEventPane eventPane; + //移动端属性容器 + private JPanel mobileTabPane; + private JPanel mobileCardPane; + private CardLayout mobileCardLayout; + private ElementCasePane pane; public CellWidgetCardPane(ElementCasePane pane) { @@ -51,27 +61,45 @@ public class CellWidgetCardPane extends BasicPane { this.removeAll(); this.setLayout(FRGUIPaneFactory.createBorderLayout()); - //k tabbedPane = new CardLayout(); center = new JPanel(tabbedPane); this.add(center, BorderLayout.CENTER); + + // 属性 attriTabPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - eventTabPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - eventTabPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); - initPaneList(); - eventPane = initWidgetEventPane(pane); - eventTabPane.add(eventPane, BorderLayout.CENTER); - //k BasicScrollPane basicScrollPane = new AttrScrollPane() { @Override protected JPanel createContentPane() { return attriTabPane; } }; + widgetPropertyPane = new BasicWidgetPropertySettingPane(); + UIExpandablePane uiExpandablePane = new UIExpandablePane(Inter.getLocText("FR-Designer_Basic"), 280, 24, widgetPropertyPane); + attriTabPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); + attriTabPane.add(uiExpandablePane, BorderLayout.NORTH); + attriCardPane = FRGUIPaneFactory.createCardLayout_S_Pane(); + attriTabPane.add(attriCardPane, BorderLayout.CENTER); + attriCardLayout = (CardLayout) attriCardPane.getLayout(); + + // 事件 + eventTabPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + eventTabPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + eventPane = initWidgetEventPane(pane); + eventTabPane.add(eventPane, BorderLayout.CENTER); + + // 移动端 + mobileTabPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + mobileCardPane = FRGUIPaneFactory.createCardLayout_S_Pane(); + mobileTabPane.add(mobileCardPane, BorderLayout.CENTER); + mobileCardLayout = (CardLayout) mobileCardPane.getLayout(); + center.add(basicScrollPane, Inter.getLocText("FR-Designer_Attribute")); center.add(eventTabPane, Inter.getLocText("FR-Designer_Event")); - final String[] tabTitles = new String[]{Inter.getLocText("FR-Designer_Attribute"), Inter.getLocText("FR-Designer_Event")}; + center.add(mobileTabPane, Inter.getLocText("FR-Widget_Mobile_Terminal")); + initPaneList(); + + final String[] tabTitles = new String[]{Inter.getLocText("FR-Designer_Attribute"), Inter.getLocText("FR-Designer_Event"), Inter.getLocText("FR-Widget_Mobile_Terminal")}; tabsHeaderIconPane = new UIHeadGroup(tabTitles) { @Override public void tabChanged(int index) { @@ -81,24 +109,13 @@ public class CellWidgetCardPane extends BasicPane { tabsHeaderIconPane.setNeedLeftRightOutLine(true); tabsHeaderIconPane.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIConstants.SHADOW_GREY)); this.add(tabsHeaderIconPane, BorderLayout.NORTH); - - widgetPropertyPane = new BasicWidgetPropertySettingPane(); - - UIExpandablePane uiExpandablePane = new UIExpandablePane(Inter.getLocText("FR-Designer_Basic"), 280, 24, widgetPropertyPane); - - - attriTabPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); - attriTabPane.add(uiExpandablePane, BorderLayout.NORTH); - - attriCardPane = FRGUIPaneFactory.createCardLayout_S_Pane(); - attriTabPane.add(attriCardPane, BorderLayout.CENTER); - attriCardLayout = (CardLayout) attriCardPane.getLayout(); } private void initPaneList() { paneList = new ArrayList(); paneList.add(attriTabPane); paneList.add(eventPane); + paneList.add(mobileTabPane); } protected WidgetEventPane initWidgetEventPane(ElementCasePane pane){ @@ -112,7 +129,6 @@ public class CellWidgetCardPane extends BasicPane { public void populate(Widget cellWidget) { initComponents(pane); - currentEditorDefinePane = null; WidgetDefinePaneFactory.RN rn = WidgetDefinePaneFactory.createWidgetDefinePane(cellWidget, new Operator() { @Override @@ -123,9 +139,17 @@ public class CellWidgetCardPane extends BasicPane { DataModify definePane = rn.getDefinePane(); attriCardPane.add(definePane.toSwingComponent(), rn.getCardName()); attriCardLayout.show(attriCardPane, rn.getCardName()); + widgetPropertyPane.populate(cellWidget); currentEditorDefinePane = definePane; + eventPane.populate(cellWidget); - widgetPropertyPane.populate(cellWidget); + + WidgetMobilePane mobilePane = WidgetMobilePaneFactory.createWidgetMobilePane(cellWidget); + mobileCardPane.add(mobilePane, mobilePane.getClass().toString()); + mobileCardLayout.show(mobileCardPane, mobilePane.getClass().toString()); + currentWidgetMobilePane = mobilePane; + + tabsHeaderIconPane.setSelectedIndex(0); } @@ -145,6 +169,8 @@ public class CellWidgetCardPane extends BasicPane { widget.addListener(l); } + currentWidgetMobilePane.update(widget); + return widget; } diff --git a/designer-realize/src/com/fr/design/widget/WidgetMobilePaneFactory.java b/designer-realize/src/com/fr/design/widget/WidgetMobilePaneFactory.java new file mode 100644 index 000000000..8b9afc3f2 --- /dev/null +++ b/designer-realize/src/com/fr/design/widget/WidgetMobilePaneFactory.java @@ -0,0 +1,39 @@ +package com.fr.design.widget; + +import com.fr.base.FRContext; +import com.fr.design.ExtraDesignClassManager; +import com.fr.design.widget.mobile.WidgetMobilePane; +import com.fr.design.widget.ui.mobile.MultiFileEditorMobilePane; +import com.fr.form.ui.MultiFileEditor; +import com.fr.form.ui.Widget; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by plough on 2018/4/25. + */ +public class WidgetMobilePaneFactory { + private static Map, Class> mobilePaneMap = new HashMap<>(); + + static { + mobilePaneMap.put(MultiFileEditor.class, MultiFileEditorMobilePane.class); + mobilePaneMap.putAll(ExtraDesignClassManager.getInstance().getCellWidgetMobileOptionsMap()); + } + + private WidgetMobilePaneFactory() { + } + + public static WidgetMobilePane createWidgetMobilePane(Widget widget) { + WidgetMobilePane mobilePane = WidgetMobilePane.DEFAULT_PANE; + try { + if (mobilePaneMap.containsKey(widget.getClass())) { + mobilePane = mobilePaneMap.get(widget.getClass()).newInstance(); + mobilePane.populate(widget); + } + } catch (Exception e) { + FRContext.getLogger().error(e.getMessage(), e); + } + return mobilePane; + } +} diff --git a/designer-realize/src/com/fr/design/widget/ui/mobile/MultiFileEditorMobilePane.java b/designer-realize/src/com/fr/design/widget/ui/mobile/MultiFileEditorMobilePane.java new file mode 100644 index 000000000..e88e0c05e --- /dev/null +++ b/designer-realize/src/com/fr/design/widget/ui/mobile/MultiFileEditorMobilePane.java @@ -0,0 +1,84 @@ +package com.fr.design.widget.ui.mobile; + +import com.fr.base.mobile.FileUploadModeState; +import com.fr.base.mobile.MultiFileUploaderMobileAttr; +import com.fr.design.constants.LayoutConstants; +import com.fr.design.designer.properties.items.Item; +import com.fr.design.foldablepane.UIExpandablePane; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.widget.mobile.WidgetMobilePane; +import com.fr.form.ui.MultiFileEditor; +import com.fr.form.ui.Widget; +import com.fr.general.Inter; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Component; + +/** + * Created by plough on 2018/4/25. + */ +public class MultiFileEditorMobilePane extends WidgetMobilePane { + private static final Item[] ITEMS = { + new Item(Inter.getLocText("FR-Designer_Take_Photos_And_Choose_From_Album"), FileUploadModeState.TAKE_PHOTOS_AND_CHOOSE_FROM_ALBUM), + new Item(Inter.getLocText("FR-Designer_Only_Take_Photos"), FileUploadModeState.ONLY_TAKE_PHOTOS) + }; + + private UIComboBox uploadModeComboBox;// 上传方式下拉框 + + protected void init() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.add(getMobileSettingsPane(), BorderLayout.NORTH); + } + + /** + * 从 widget 中提取数据展示在属性面板中 + * + * @param widget + */ + public void populate(Widget widget) { + MultiFileUploaderMobileAttr mobileAttr = ((MultiFileEditor)widget).getMobileAttr(); + FileUploadModeState fileUploadModeState = mobileAttr.getFileUploadModeState(); + uploadModeComboBox.setSelectedIndex(fileUploadModeState.getState()); + } + + /** + * 从属性面板把数据保存到 widget 中 + * @param widget + */ + public void update(Widget widget) { + MultiFileUploaderMobileAttr mobileAttr = ((MultiFileEditor)widget).getMobileAttr(); + mobileAttr.setFileUploadModeState((FileUploadModeState) ((Item)uploadModeComboBox.getSelectedItem()).getValue()); + } + + private UIExpandablePane getMobileSettingsPane() { + initUploadModeComboBox(); + + // 以后可能会扩展 + Component[][] components = new Component[][]{ + new Component[] {new UILabel(Inter.getLocText("FR-Designer_Upload_Mode"), SwingConstants.LEFT), uploadModeComboBox} + }; + + double f = TableLayout.FILL; + double p = TableLayout.PREFERRED; + double[] rowSize = {p}; + double[] columnSize = {p,f}; + int[][] rowCount = {{1, 1}}; + final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 30, LayoutConstants.VGAP_LARGE); + panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + final JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panelWrapper.add(panel, BorderLayout.NORTH); + + return new UIExpandablePane(Inter.getLocText("FR-Designer_Terminal"), 280, 20, panelWrapper); + } + + private void initUploadModeComboBox() { + this.uploadModeComboBox = new UIComboBox(ITEMS); + } +} From 29a7ae32b6793a7aff86d4f89bd138fac891ded4 Mon Sep 17 00:00:00 2001 From: richie Date: Thu, 7 Jun 2018 17:44:12 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E6=97=A0JIRA=E4=BB=BB=E5=8A=A1=20=E8=BF=9C?= =?UTF-8?q?=E7=A8=8B=E8=AE=BE=E8=AE=A1=E7=95=8C=E9=9D=A2=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=AF=B9=E5=BA=94=E4=BF=AE=E6=94=B9=EF=BC=88=E9=83=A8=E5=88=86?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gui/itextfield/PlaceholderTextField.java | 26 ---- .../gui/itextfield}/UIIntNumberField.java | 2 +- .../fr/design/gui/itextfield/UITextField.java | 32 +++- designer-base/src/com/fr/env/EnvListPane.java | 5 +- designer-base/src/com/fr/env/RemoteEnv.java | 42 +++-- .../src/com/fr/env/RemoteEnvPane2.java | 145 ++++++++++++++++++ .../fr/design/report/freeze/RowSpinner.java | 1 + 7 files changed, 208 insertions(+), 45 deletions(-) rename {designer-realize/src/com/fr/design/report/freeze => designer-base/src/com/fr/design/gui/itextfield}/UIIntNumberField.java (97%) create mode 100644 designer-base/src/com/fr/env/RemoteEnvPane2.java diff --git a/designer-base/src/com/fr/design/gui/itextfield/PlaceholderTextField.java b/designer-base/src/com/fr/design/gui/itextfield/PlaceholderTextField.java index 3ff686099..30204aee7 100644 --- a/designer-base/src/com/fr/design/gui/itextfield/PlaceholderTextField.java +++ b/designer-base/src/com/fr/design/gui/itextfield/PlaceholderTextField.java @@ -1,12 +1,9 @@ package com.fr.design.gui.itextfield; import javax.swing.text.Document; -import java.awt.*; public class PlaceholderTextField extends UITextField { - private String placeholder; - public PlaceholderTextField() { } @@ -28,27 +25,4 @@ public class PlaceholderTextField extends UITextField { public PlaceholderTextField(final String pText, final int pColumns) { super(pText, pColumns); } - - public String getPlaceholder() { - return placeholder; - } - - @Override - protected void paintComponent(final Graphics pG) { - super.paintComponent(pG); - if (placeholder.length() == 0 || getText().length() > 0) { - return; - } - final Graphics2D g = (Graphics2D) pG; - g.setRenderingHint( - RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - g.setColor(getDisabledTextColor()); - g.drawString(placeholder, getInsets().left, pG.getFontMetrics() - .getMaxAscent() + getInsets().top + 1); - } - - public void setPlaceholder(final String s) { - placeholder = s; - } } \ No newline at end of file diff --git a/designer-realize/src/com/fr/design/report/freeze/UIIntNumberField.java b/designer-base/src/com/fr/design/gui/itextfield/UIIntNumberField.java similarity index 97% rename from designer-realize/src/com/fr/design/report/freeze/UIIntNumberField.java rename to designer-base/src/com/fr/design/gui/itextfield/UIIntNumberField.java index c42c5b1d8..59e5e8825 100644 --- a/designer-realize/src/com/fr/design/report/freeze/UIIntNumberField.java +++ b/designer-base/src/com/fr/design/gui/itextfield/UIIntNumberField.java @@ -1,4 +1,4 @@ -package com.fr.design.report.freeze; +package com.fr.design.gui.itextfield; import com.fr.design.gui.itextfield.UINumberField; diff --git a/designer-base/src/com/fr/design/gui/itextfield/UITextField.java b/designer-base/src/com/fr/design/gui/itextfield/UITextField.java index e4f5b9d87..98823bee9 100644 --- a/designer-base/src/com/fr/design/gui/itextfield/UITextField.java +++ b/designer-base/src/com/fr/design/gui/itextfield/UITextField.java @@ -7,6 +7,7 @@ import com.fr.design.event.UIObserver; import com.fr.design.event.UIObserverListener; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.stable.Constants; +import com.fr.stable.StringUtils; import javax.swing.*; import javax.swing.event.DocumentEvent; @@ -22,9 +23,10 @@ public class UITextField extends JTextField implements UIObserver, GlobalNameObs private boolean isRoundBorder = true; private int rectDirection = Constants.NULL; private UIObserverListener uiObserverListener; - private String textFeildName = ""; + private String textFieldName = StringUtils.EMPTY; private GlobalNameListener globalNameListener = null; private Dimension preferredSize = null; + private String placeholder = StringUtils.EMPTY; //有些情况下setText的时候不希望触发attributeChange,添加一个属性标识 private boolean isSetting = false; @@ -81,6 +83,15 @@ public class UITextField extends JTextField implements UIObserver, GlobalNameObs } } + public String getPlaceholder() { + return placeholder; + } + + public void setPlaceholder(String placeholder) { + this.placeholder = placeholder; + } + + public boolean isSetting() { return isSetting; } @@ -94,7 +105,7 @@ public class UITextField extends JTextField implements UIObserver, GlobalNameObs } public void setGlobalName(String name) { - textFeildName = name; + textFieldName = name; } protected void attributeChange() { @@ -102,7 +113,7 @@ public class UITextField extends JTextField implements UIObserver, GlobalNameObs return; } if (globalNameListener != null && shouldResponseNameListener()) { - globalNameListener.setGlobalName(textFeildName); + globalNameListener.setGlobalName(textFieldName); } if (uiObserverListener != null) { uiObserverListener.doChange(); @@ -141,6 +152,21 @@ public class UITextField extends JTextField implements UIObserver, GlobalNameObs this.setUI(new UITextFieldUI(this)); } + @Override + protected void paintComponent(final Graphics pG) { + super.paintComponent(pG); + if (placeholder.length() == 0 || getText().length() > 0) { + return; + } + final Graphics2D g = (Graphics2D) pG; + g.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.setColor(getDisabledTextColor()); + g.drawString(placeholder, getInsets().left, pG.getFontMetrics() + .getMaxAscent() + getInsets().top + 1); + } + @Override protected void paintBorder(Graphics g) { if (!isBorderPainted) { diff --git a/designer-base/src/com/fr/env/EnvListPane.java b/designer-base/src/com/fr/env/EnvListPane.java index 1927f127a..92bab2929 100644 --- a/designer-base/src/com/fr/env/EnvListPane.java +++ b/designer-base/src/com/fr/env/EnvListPane.java @@ -14,8 +14,7 @@ import com.fr.stable.Nameable; import com.fr.stable.StringUtils; import com.fr.stable.core.PropertyChangeAdapter; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; +import javax.swing.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -62,7 +61,7 @@ public class EnvListPane extends JListControlPane { NameableCreator local = new NameObjectCreator(Inter.getLocText("Env-Local_Directory"), "com/fr/design/images/data/bind/localconnect.png", LocalEnvConfig.class, LocalEnvPane.class); NameableCreator remote = new NameObjectCreator(Inter.getLocText("Env-Remote_Server"), "com/fr/design/images/data/bind/distanceconnect.png", - RemoteEnvConfig.class, RemoteEnvPane.class); + RemoteEnvConfig.class, RemoteEnvPane2.class); return new NameableCreator[]{local, remote}; } diff --git a/designer-base/src/com/fr/env/RemoteEnv.java b/designer-base/src/com/fr/env/RemoteEnv.java index c52890ecb..ffb42c122 100644 --- a/designer-base/src/com/fr/env/RemoteEnv.java +++ b/designer-base/src/com/fr/env/RemoteEnv.java @@ -2,11 +2,12 @@ package com.fr.env; import com.fr.base.EnvException; import com.fr.base.TableData; +import com.fr.base.operator.connect.ConnectOperator; import com.fr.base.operator.file.FileOperator; import com.fr.base.remote.RemoteDeziConstants; import com.fr.common.rpc.RemoteCallServerConfig; import com.fr.common.rpc.netty.MessageSendExecutor; -import com.fr.common.rpc.serialize.SerializeProtocol; +import com.fr.common.rpc.netty.RemoteCallClient; import com.fr.core.env.EnvConstants; import com.fr.core.env.EnvContext; import com.fr.core.env.resource.RemoteEnvConfig; @@ -49,7 +50,7 @@ import com.fr.third.guava.base.Strings; import com.fr.third.guava.collect.ImmutableMap; import com.fr.web.ResourceConstants; -import javax.swing.JOptionPane; +import javax.swing.*; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; @@ -57,7 +58,7 @@ import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import java.awt.Component; +import java.awt.*; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -79,24 +80,41 @@ import static com.fr.third.guava.base.Preconditions.checkArgument; /** * @author null */ -public class RemoteEnv extends AbstractEnv implements DesignAuthorityConfigurable { +public class RemoteEnv extends AbstractEnv implements DesignAuthorityConfigurable { private static final String CERT_KEY = "javax.net.ssl.trustStore"; private static final String PWD_KEY = "javax.net.ssl.trustStorePassword"; private static final String HTTPS_PREFIX = "https:"; private final static String[] FILE_TYPE = {"cptx", "cpt", "frm", "form", "cht", "chart"}; private String buildFilePath; - private RemoteEnvConfig env; + private RemoteEnvConfig config; + public RemoteEnv(RemoteEnvConfig config) { + this.config = config; + } public RemoteEnv(String path, String userName, String password) { - env = new RemoteEnvConfig(path, userName, password); + config = new RemoteEnvConfig(path, userName, password); + } + + @Override + public void connect() throws Exception { + } @Override - public void connect() { - // FIXME:richie ip地址属于测试的,带实际修改为RemoteEnv配置的地址 - MessageSendExecutor.getInstance().setRpcServerLoader("127.0.0.1", RemoteCallServerConfig.getInstance().getPort(), RemoteCallServerConfig.getInstance().getSerializeProtocol()); + public void connectOnce() throws Exception { + RemoteCallClient.getInstance().loadOnce(config.getHost(), config.getPort(), RemoteCallServerConfig.getInstance().getSerializeProtocol(), 10 * 1000); + ConnectOperator operator = RemoteCallClient.getInstance().execute(ConnectOperator.class); + boolean result = false; + try { + result = operator.connect(config.getUsername(), config.getPassword()); + } catch (Exception ignore) { + + } + if (!result) { + throw new Exception("Cannot connect to the remote server!"); + } } @Override @@ -112,16 +130,16 @@ public class RemoteEnv extends AbstractEnv implements DesignAuthorityConfigurabl @Override public String getPath() { - return env.getPath(); + return config.getPath(); } @Override public String getUser() { - return env.getUsername(); + return config.getUsername(); } public String getPassword() { - return env.getPassword(); + return config.getPassword(); } @Override diff --git a/designer-base/src/com/fr/env/RemoteEnvPane2.java b/designer-base/src/com/fr/env/RemoteEnvPane2.java new file mode 100644 index 000000000..11bd73cef --- /dev/null +++ b/designer-base/src/com/fr/env/RemoteEnvPane2.java @@ -0,0 +1,145 @@ +package com.fr.env; + +import com.fr.core.env.resource.RemoteEnvConfig; +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.border.UITitledBorder; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.ipasswordfield.UIPassWordField; +import com.fr.design.gui.itextfield.UIIntNumberField; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.Inter; +import com.fr.log.FineLoggerFactory; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.concurrent.ExecutionException; + +/** + * 远程环境设置界面,暂时命名为2,待做完功能直接替代掉老的RemoteEnvPane + */ +public class RemoteEnvPane2 extends BasicBeanPane { + + private UITextField hostTextField; + private UIIntNumberField portTextField; + private UITextField usernameTextField; + private UIPassWordField passwordTextField; + + public RemoteEnvPane2() { + initComponents(); + } + + private void initComponents() { + setLayout(new BorderLayout()); + + JPanel contentPanel = new JPanel(new BorderLayout()); + add(contentPanel, BorderLayout.CENTER); + + contentPanel.setBorder( + BorderFactory.createCompoundBorder( + new EmptyBorder(6, 0, 0, 0), + UITitledBorder.createBorderWithTitle(Inter.getLocText("Fine-Designer_Basic_Remote_Env_Config"))) + ); + + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] rowSize = new double[]{p, p, p, p, p}; + double[] columnSize = new double[]{p, f}; + UIButton testConnectionButton = new UIButton(Inter.getLocText("Fine-Designer_Basic_Remote_Env_Try")); + hostTextField = new UITextField(); + hostTextField.setPlaceholder("192.168.100.200"); + portTextField = new UIIntNumberField(); + portTextField.setPlaceholder("39999"); + JPanel valuePane = TableLayoutHelper.createTableLayoutPane( + new Component[][]{ + {new UILabel(Inter.getLocText("Fine-Designer_Basic_Remote_Env_Host") + ":", SwingConstants.RIGHT), hostTextField}, + {new UILabel(Inter.getLocText("Fine-Designer_Basic_Remote_Env_Port") + ":", SwingConstants.RIGHT),portTextField}, + {new UILabel(Inter.getLocText("Fine-Designer_Basic_Remote_Env_User") + ":", SwingConstants.RIGHT), usernameTextField = new UITextField()}, + {new UILabel(Inter.getLocText("Fine-Designer_Basic_Remote_Env_Password") + ":", SwingConstants.RIGHT), passwordTextField = new UIPassWordField()}, + {null, GUICoreUtils.createFlowPane(testConnectionButton, FlowLayout.LEFT)} + }, + rowSize, columnSize + ); + testConnectionButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + tryConnectRemoteEnv(); + } + }); + contentPanel.add(valuePane, BorderLayout.CENTER); + } + + private void tryConnectRemoteEnv() { + final RemoteEnv remoteEnv = new RemoteEnv(this.updateBean()); + new SwingWorker() { + + @Override + protected Void doInBackground() throws Exception { + remoteEnv.connectOnce(); + return null; + } + + @Override + protected void done() { + try { + get(); + showConnectMessage(); + } catch (Exception e) { + showCannotConnectMessage(); + } + } + }.execute(); + } + + private void showCannotConnectMessage() { + JOptionPane.showMessageDialog( + this, + Inter.getLocText("Fine-Designer_Basic_Remote_Connect_Failed"), + UIManager.getString("OptionPane.messageDialogTitle", this.getLocale()), + JOptionPane.ERROR_MESSAGE + ); + } + + private void showConnectMessage() { + JOptionPane.showMessageDialog( + this, + Inter.getLocText("Fine-Designer_Basic_Remote_Connect_Successful"), + UIManager.getString("OptionPane.messageDialogTitle", this.getLocale()), + JOptionPane.INFORMATION_MESSAGE + ); + } + + @Override + protected String title4PopupWindow() { + return "RemoteEnv"; + } + + @Override + public void populateBean(RemoteEnvConfig config) { + if (config == null) { + return; + } + hostTextField.setText(config.getPath()); + if (config.getPort() != 0) { + portTextField.setValue(config.getPort()); + } + usernameTextField.setText(config.getUsername()); + passwordTextField.setText(config.getPassword()); + } + + @Override + public RemoteEnvConfig updateBean() { + RemoteEnvConfig config = new RemoteEnvConfig(); + config.setHost(hostTextField.getText()); + config.setPort((int) portTextField.getValue()); + config.setUsername(usernameTextField.getText()); + config.setPassword(passwordTextField.getText()); + return config; + } +} diff --git a/designer-realize/src/com/fr/design/report/freeze/RowSpinner.java b/designer-realize/src/com/fr/design/report/freeze/RowSpinner.java index 17df3be52..da652a0e4 100644 --- a/designer-realize/src/com/fr/design/report/freeze/RowSpinner.java +++ b/designer-realize/src/com/fr/design/report/freeze/RowSpinner.java @@ -1,6 +1,7 @@ package com.fr.design.report.freeze; import com.fr.design.gui.ispinner.UISpinner; +import com.fr.design.gui.itextfield.UIIntNumberField; import com.fr.design.gui.itextfield.UINumberField; /** From fe3a74f6807590c61d2e51a5c7332a845d5e05b2 Mon Sep 17 00:00:00 2001 From: plough Date: Thu, 7 Jun 2018 17:56:30 +0800 Subject: [PATCH 5/9] =?UTF-8?q?REPORT-8355=209.0=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E7=9A=84=E5=8A=9F=E8=83=BD=E4=B8=8Ebug=20pat?= =?UTF-8?q?ch=E5=88=B010.0=EF=BC=88=E9=83=A8=E5=88=86=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractCellWidgetOptionProvider.java | 6 + .../src/com/fr/design/gui/ilable/UILabel.java | 22 +- .../design/designer/creator/XChartEditor.java | 145 +++++++------ .../designer/creator/XWParameterLayout.java | 47 +++-- .../mobile/ChartEditorPropertyUI.java | 36 ++++ .../mobile/ParaMobilePropertyUI.java | 36 ++++ .../fr/design/mainframe/CoverReportPane.java | 4 +- .../mainframe/EditingMouseListener.java | 93 +++++---- .../designer/mobile/BodyMobileDefinePane.java | 124 +++++++++++ .../mobile/ChartEditorDefinePane.java | 196 ++++++++++++++++++ .../mobile/MultiFileUploaderDefinePane.java | 110 ++++++++++ .../designer/mobile/ParaMobileDefinePane.java | 81 ++++++++ .../report/ReportMobileAttrAction.java | 26 ++- .../mainframe/CellWidgetPropertyPane.java | 12 +- .../com/fr/design/webattr/EditToolBar.java | 87 ++------ .../com/fr/design/webattr/ToolBarPane.java | 70 ++++--- 16 files changed, 869 insertions(+), 226 deletions(-) create mode 100644 designer-form/src/com/fr/design/designer/properties/mobile/ChartEditorPropertyUI.java create mode 100644 designer-form/src/com/fr/design/designer/properties/mobile/ParaMobilePropertyUI.java create mode 100644 designer-form/src/com/fr/design/widget/ui/designer/mobile/BodyMobileDefinePane.java create mode 100644 designer-form/src/com/fr/design/widget/ui/designer/mobile/ChartEditorDefinePane.java create mode 100644 designer-form/src/com/fr/design/widget/ui/designer/mobile/MultiFileUploaderDefinePane.java create mode 100644 designer-form/src/com/fr/design/widget/ui/designer/mobile/ParaMobileDefinePane.java diff --git a/designer-base/src/com/fr/design/fun/impl/AbstractCellWidgetOptionProvider.java b/designer-base/src/com/fr/design/fun/impl/AbstractCellWidgetOptionProvider.java index 8e040bcd9..1efbdd80e 100644 --- a/designer-base/src/com/fr/design/fun/impl/AbstractCellWidgetOptionProvider.java +++ b/designer-base/src/com/fr/design/fun/impl/AbstractCellWidgetOptionProvider.java @@ -1,6 +1,7 @@ package com.fr.design.fun.impl; import com.fr.design.fun.CellWidgetOptionProvider; +import com.fr.design.widget.mobile.WidgetMobilePane; import com.fr.stable.fun.impl.AbstractProvider; import com.fr.stable.fun.mark.API; @@ -20,4 +21,9 @@ public abstract class AbstractCellWidgetOptionProvider extends AbstractProvider public String mark4Provider() { return getClass().getName(); } + + @Override + public Class classForMobilePane() { + return WidgetMobilePane.class; + } } \ No newline at end of file diff --git a/designer-base/src/com/fr/design/gui/ilable/UILabel.java b/designer-base/src/com/fr/design/gui/ilable/UILabel.java index f90dbea0d..6583e8d61 100644 --- a/designer-base/src/com/fr/design/gui/ilable/UILabel.java +++ b/designer-base/src/com/fr/design/gui/ilable/UILabel.java @@ -1,9 +1,16 @@ package com.fr.design.gui.ilable; import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.stable.StringUtils; -import javax.swing.*; -import java.awt.*; +import com.fr.stable.StringUtils; +import javax.swing.Icon; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; /** * Created by IntelliJ IDEA. @@ -13,6 +20,7 @@ import java.awt.*; * Time: 下午3:15 */ public class UILabel extends JLabel { + private static final int HTML_SHIFT_HEIGHT = 3; public UILabel(String text, Icon image, int horizontalAlignment) { super(text, image, horizontalAlignment); @@ -46,6 +54,16 @@ public class UILabel extends JLabel { super(); } + @Override + public Dimension getPreferredSize() { + Dimension preferredSize = super.getPreferredSize(); + // (Windows 下)使用 html 时,文字内容会略微向下偏移,导致文字底部被截断,所以适当增加 UILabel 的高度 + if (StringUtils.isNotEmpty(getText()) && getText().startsWith("")) { + return new Dimension(preferredSize.width, preferredSize.height + HTML_SHIFT_HEIGHT); + } + return preferredSize; + } + public static void main(String[] args) { // UILabel label = new UILabel("shishi",SwingConstants.LEFT); diff --git a/designer-form/src/com/fr/design/designer/creator/XChartEditor.java b/designer-form/src/com/fr/design/designer/creator/XChartEditor.java index a53aae956..bb730122a 100644 --- a/designer-form/src/com/fr/design/designer/creator/XChartEditor.java +++ b/designer-form/src/com/fr/design/designer/creator/XChartEditor.java @@ -11,11 +11,13 @@ import com.fr.base.chart.BaseChartCollection; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.models.SelectionModel; +import com.fr.design.designer.properties.mobile.ChartEditorPropertyUI; +import com.fr.design.designer.properties.mobile.ElementCasePropertyUI; +import com.fr.design.fun.WidgetPropertyUIProvider; import com.fr.design.gui.chart.BaseChartPropertyPane; import com.fr.design.gui.chart.MiddleChartComponent; import com.fr.design.mainframe.*; import com.fr.design.mainframe.widget.editors.WLayoutBorderStyleEditor; -import com.fr.design.mainframe.widget.renderer.LayoutBorderStyleRenderer; import com.fr.design.module.DesignModuleFactory; import com.fr.design.designer.beans.events.DesignerEditor; import com.fr.form.ui.BaseChartEditor; @@ -23,6 +25,7 @@ import com.fr.form.ui.Widget; import com.fr.design.form.util.XCreatorConstants; import com.fr.general.Inter; import com.fr.stable.Constants; +import com.fr.stable.GraphDrawHelper; import com.fr.stable.core.PropertyChangeAdapter; /** @@ -35,18 +38,17 @@ import com.fr.stable.core.PropertyChangeAdapter; public class XChartEditor extends XBorderStyleWidgetCreator { private static final long serialVersionUID = -7009439442104836657L; private static final int BORDER_WIDTH = 2; - //具体来说是DesignerEditor private DesignerEditor designerEditor; // private DesignerEditor designerEditor; //marro:无奈的属性,暂时想不出好办法 private boolean isRefreshing = false; - private boolean isHovering = false; private boolean isEditing = false; + + private boolean isHovering = false; private static final Color OUTER_BORDER_COLOR = new Color(65, 155, 249, 30); private static final Color INNER_BORDER_COLOR = new Color(65, 155, 249); - private JPanel coverPanel; public XChartEditor(BaseChartEditor editor) { this(editor, new Dimension(250, 150)); @@ -67,19 +69,19 @@ public class XChartEditor extends XBorderStyleWidgetCreator { return "Chart.png"; } - /** - * 返回组件默认名 - * @return 组件类名(小写) - */ - public String createDefaultName() { - return "chart"; - } - - /** - * 是否支持设置标题 - * @return 是返回true - */ - public boolean hasTitleStyle() { + /** + * 返回组件默认名 + * @return 组件类名(小写) + */ + public String createDefaultName() { + return "chart"; + } + + /** + * 是否支持设置标题 + * @return 是返回true + */ + public boolean hasTitleStyle() { return true; } @@ -88,15 +90,15 @@ public class XChartEditor extends XBorderStyleWidgetCreator { isEditing = false; } - /** - * 得到属性名 - * @return 属性名 - * @throws java.beans.IntrospectionException - */ - public CRPropertyDescriptor[] supportedDescriptor() throws IntrospectionException { - return new CRPropertyDescriptor[] { - new CRPropertyDescriptor("widgetName", this.data.getClass()).setI18NName(Inter - .getLocText("Form-Widget_Name")), + /** + * 得到属性名 + * @return 属性名 + * @throws java.beans.IntrospectionException + */ + public CRPropertyDescriptor[] supportedDescriptor() throws IntrospectionException { + return new CRPropertyDescriptor[] { + new CRPropertyDescriptor("widgetName", this.data.getClass()).setI18NName(Inter + .getLocText("Form-Widget_Name")), new CRPropertyDescriptor("visible", this.data.getClass()).setI18NName( Inter.getLocText("FR-Designer_Widget-Visible")).setPropertyChangeListener(new PropertyChangeAdapter() { @@ -104,26 +106,42 @@ public class XChartEditor extends XBorderStyleWidgetCreator { public void propertyChange() { makeVisible(toData().isVisible());} }), - new CRPropertyDescriptor("borderStyle", this.data.getClass()).setEditorClass( - WLayoutBorderStyleEditor.class).setI18NName( - Inter.getLocText("Chart-Style_Name")).putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Advanced") - .setPropertyChangeListener(new PropertyChangeAdapter() { - - @Override - public void propertyChange() { - initStyle(); - } - }), - }; - } - - /** - * 该组件是否可以拖入参数面板 - * @return 是则返回true - */ - public boolean canEnterIntoParaPane(){ - return false; - } + new CRPropertyDescriptor("borderStyle", this.data.getClass()).setEditorClass( + WLayoutBorderStyleEditor.class).setI18NName( + Inter.getLocText("Chart-Style_Name")).putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Advanced") + .setPropertyChangeListener(new PropertyChangeAdapter() { + + @Override + public void propertyChange() { + initStyle(); + } + }), + }; + } + + /** + * 该组件是否可以拖入参数面板 + * @return 是则返回true + */ + public boolean canEnterIntoParaPane(){ + return false; + } + + + /** + * 编辑状态的时候需要重新绘制下边框 + * + */ + @Override + public void paintBorder(Graphics g, Rectangle bounds){ + if(isEditing){ + g.setColor(OUTER_BORDER_COLOR); + GraphHelper.draw(g, new Rectangle(bounds.x - BORDER_WIDTH, bounds.y - BORDER_WIDTH, bounds.width + BORDER_WIDTH + 1, bounds.height + BORDER_WIDTH + 1), Constants.LINE_LARGE); + }else if(!isHovering){ + super.paintBorder(g, bounds); + } + } + /** * 返回设计器的Editor @@ -187,22 +205,6 @@ public class XChartEditor extends XBorderStyleWidgetCreator { return bcc; } - - /** - * 编辑状态的时候需要重新绘制下边框 - * - */ - @Override - public void paintBorder(Graphics g, Rectangle bounds){ - if(isEditing){ - g.setColor(OUTER_BORDER_COLOR); - GraphHelper.draw(g, new Rectangle(bounds.x - BORDER_WIDTH, bounds.y - BORDER_WIDTH, bounds.width + BORDER_WIDTH + 1, bounds.height + BORDER_WIDTH + 1), Constants.LINE_LARGE); - }else if(!isHovering){ - super.paintBorder(g, bounds); - } - } - - /** * 渲染Painter */ @@ -244,6 +246,10 @@ public class XChartEditor extends XBorderStyleWidgetCreator { editingMouseListener.startEditing(this, isEditing ? adapter.getDesignerEditor() : null, adapter); } } + HelpDialogManager.getInstance().setPane(coverPanel); + if (this.isHelpBtnOnFocus()) { + coverPanel.setMsgDisplay(e); + } } @Override @@ -272,7 +278,7 @@ public class XChartEditor extends XBorderStyleWidgetCreator { editor.setLayout(null); editor.setOpaque(false); - coverPanel = new CoverPane(); + coverPanel = new CoverReportPane(); coverPanel.setPreferredSize(this.getPreferredSize()); coverPanel.setBounds(this.getBounds()); @@ -287,6 +293,7 @@ public class XChartEditor extends XBorderStyleWidgetCreator { * @param display 是否 */ public void displayCoverPane(boolean display){ + isHovering = display; coverPanel.setVisible(display); coverPanel.setPreferredSize(editor.getPreferredSize()); coverPanel.setBounds(editor.getBounds()); @@ -313,4 +320,16 @@ public class XChartEditor extends XBorderStyleWidgetCreator { initStyle(); } + @Override + public WidgetPropertyUIProvider[] getWidgetPropertyUIProviders() { + return new WidgetPropertyUIProvider[]{ new ChartEditorPropertyUI(this)}; + } + + /** + * 是否支持共享-现只支持报表块、图表、tab块、绝对布局 + * @return + */ + public boolean isSupportShared() { + return true; + } } \ No newline at end of file diff --git a/designer-form/src/com/fr/design/designer/creator/XWParameterLayout.java b/designer-form/src/com/fr/design/designer/creator/XWParameterLayout.java index a397996a3..bd92dfe71 100644 --- a/designer-form/src/com/fr/design/designer/creator/XWParameterLayout.java +++ b/designer-form/src/com/fr/design/designer/creator/XWParameterLayout.java @@ -6,7 +6,9 @@ package com.fr.design.designer.creator; import com.fr.design.ExtraDesignClassManager; import com.fr.design.designer.beans.LayoutAdapter; import com.fr.design.designer.beans.adapters.layout.FRParameterLayoutAdapter; +import com.fr.design.designer.properties.mobile.ParaMobilePropertyUI; import com.fr.design.form.util.XCreatorConstants; +import com.fr.design.fun.WidgetPropertyUIProvider; import com.fr.design.mainframe.widget.editors.BackgroundEditor; import com.fr.design.mainframe.widget.editors.BooleanEditor; import com.fr.design.mainframe.widget.editors.WidgetDisplayPosition; @@ -28,18 +30,18 @@ import java.beans.PropertyDescriptor; * 表单参数界面container */ public class XWParameterLayout extends XWAbsoluteLayout { - - public XWParameterLayout() { - this(new WParameterLayout(), new Dimension()); - } - - public XWParameterLayout(WParameterLayout widget) { - this(widget,new Dimension()); - } - public XWParameterLayout(WParameterLayout widget, Dimension initSize) { - super(widget, initSize); - } + public XWParameterLayout() { + this(new WParameterLayout(), new Dimension()); + } + + public XWParameterLayout(WParameterLayout widget) { + this(widget,new Dimension()); + } + + public XWParameterLayout(WParameterLayout widget, Dimension initSize) { + super(widget, initSize); + } /** * 初始化尺寸 @@ -74,11 +76,11 @@ public class XWParameterLayout extends XWAbsoluteLayout { return ArrayUtils.addAll(propertyTableEditor, getExtraTableEditor()); } - - @Override - public LayoutAdapter getLayoutAdapter() { - return new FRParameterLayoutAdapter(this); - } + + @Override + public LayoutAdapter getLayoutAdapter() { + return new FRParameterLayoutAdapter(this); + } /** * 获取插件给该控件提供的额外属性表 @@ -214,6 +216,11 @@ public class XWParameterLayout extends XWAbsoluteLayout { public void updateBoundsWidget() { } + @Override + public WidgetPropertyUIProvider[] getWidgetPropertyUIProviders() { + return new WidgetPropertyUIProvider[]{ new ParaMobilePropertyUI(this)}; + } + @Override protected String getIconName() { return "layout_absolute.png"; @@ -237,4 +244,12 @@ public class XWParameterLayout extends XWAbsoluteLayout { return false; } + /** + * 是否支持共享-现只支持报表块、图表、tab块、绝对布局 + * @return + */ + public boolean isSupportShared() { + return false; + } + } \ No newline at end of file diff --git a/designer-form/src/com/fr/design/designer/properties/mobile/ChartEditorPropertyUI.java b/designer-form/src/com/fr/design/designer/properties/mobile/ChartEditorPropertyUI.java new file mode 100644 index 000000000..6e642a635 --- /dev/null +++ b/designer-form/src/com/fr/design/designer/properties/mobile/ChartEditorPropertyUI.java @@ -0,0 +1,36 @@ +package com.fr.design.designer.properties.mobile; + +import com.fr.design.designer.creator.XChartEditor; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.dialog.BasicPane; +import com.fr.design.fun.impl.AbstractWidgetPropertyUIProvider; +import com.fr.design.gui.itable.AbstractPropertyTable; +import com.fr.design.widget.ui.designer.mobile.ChartEditorDefinePane; +import com.fr.general.Inter; + +/** + * Created by plough on 2018/1/18. + */ +public class ChartEditorPropertyUI extends AbstractWidgetPropertyUIProvider { + + private XCreator xCreator; + + public ChartEditorPropertyUI(XChartEditor xChartEditor) { + this.xCreator = xChartEditor; + } + + @Override + public AbstractPropertyTable createWidgetAttrTable() { + return null; + } + + @Override + public BasicPane createWidgetAttrPane() { + return new ChartEditorDefinePane(xCreator); + } + + @Override + public String tableTitle() { + return Inter.getLocText("FR-Designer_Mobile-Attr"); + } +} diff --git a/designer-form/src/com/fr/design/designer/properties/mobile/ParaMobilePropertyUI.java b/designer-form/src/com/fr/design/designer/properties/mobile/ParaMobilePropertyUI.java new file mode 100644 index 000000000..e9fc479fa --- /dev/null +++ b/designer-form/src/com/fr/design/designer/properties/mobile/ParaMobilePropertyUI.java @@ -0,0 +1,36 @@ +package com.fr.design.designer.properties.mobile; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XWParameterLayout; +import com.fr.design.dialog.BasicPane; +import com.fr.design.fun.impl.AbstractWidgetPropertyUIProvider; +import com.fr.design.gui.itable.AbstractPropertyTable; +import com.fr.design.widget.ui.designer.mobile.ParaMobileDefinePane; +import com.fr.general.Inter; + +/** + * Created by Administrator on 2016/5/16/0016. + */ +public class ParaMobilePropertyUI extends AbstractWidgetPropertyUIProvider { + + private XCreator xCreator; + + public ParaMobilePropertyUI(XWParameterLayout xwParameterLayout) { + this.xCreator = xwParameterLayout; + } + + @Override + public AbstractPropertyTable createWidgetAttrTable() { + return null; + } + + @Override + public BasicPane createWidgetAttrPane() { + return new ParaMobileDefinePane(xCreator); + } + + @Override + public String tableTitle() { + return Inter.getLocText("FR-Designer_Mobile-Attr"); + } +} diff --git a/designer-form/src/com/fr/design/mainframe/CoverReportPane.java b/designer-form/src/com/fr/design/mainframe/CoverReportPane.java index a47403f0f..a6ec28abb 100644 --- a/designer-form/src/com/fr/design/mainframe/CoverReportPane.java +++ b/designer-form/src/com/fr/design/mainframe/CoverReportPane.java @@ -35,7 +35,7 @@ public class CoverReportPane extends CoverPane implements HelpDialogHandler{ private String helpMsg;//帮助信息(后续帮助信息可能会变成标配,就直接放这边了) - private ElementCaseHelpDialog helpDialog = null; + private WidgetHelpDialog helpDialog = null; public CoverReportPane() { this(StringUtils.EMPTY); @@ -62,7 +62,7 @@ public class CoverReportPane extends CoverPane implements HelpDialogHandler{ if (helpDialog == null) { // controlMode = IOUtils.readIcon(IconPathConstants.TD_EL_SHARE_CLOSE_ICON_PATH); controlButton.setVisible(false); - helpDialog = new ElementCaseHelpDialog(DesignerContext.getDesignerFrame(), helpMsg); + helpDialog = new WidgetHelpDialog(DesignerContext.getDesignerFrame(), helpMsg); double screenValue = FRScreen.getByDimension(Toolkit.getDefaultToolkit().getScreenSize()).getValue(); int offsetX = 0; if (screenValue < FormArea.DEFAULT_SLIDER) { diff --git a/designer-form/src/com/fr/design/mainframe/EditingMouseListener.java b/designer-form/src/com/fr/design/mainframe/EditingMouseListener.java index 1f94f3fa6..d53865f4b 100644 --- a/designer-form/src/com/fr/design/mainframe/EditingMouseListener.java +++ b/designer-form/src/com/fr/design/mainframe/EditingMouseListener.java @@ -1,6 +1,8 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; +import com.fr.base.vcs.DesignerMode; +import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.events.DesignerEditor; @@ -9,13 +11,7 @@ import com.fr.design.designer.beans.location.Direction; import com.fr.design.designer.beans.location.Location; import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.beans.models.StateModel; -import com.fr.design.designer.creator.XChartEditor; -import com.fr.design.designer.creator.XCreator; -import com.fr.design.designer.creator.XCreatorUtils; -import com.fr.design.designer.creator.XEditorHolder; -import com.fr.design.designer.creator.XElementCase; -import com.fr.design.designer.creator.XLayoutContainer; -import com.fr.design.designer.creator.XWFitLayout; +import com.fr.design.designer.creator.*; import com.fr.design.designer.creator.cardlayout.XCardSwitchButton; import com.fr.design.designer.creator.cardlayout.XWCardLayout; import com.fr.design.form.util.XCreatorConstants; @@ -27,18 +23,13 @@ import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.LayoutUtils; import com.fr.general.Inter; +import com.fr.share.ShareConstants; import com.fr.stable.Constants; -import javax.swing.BorderFactory; -import javax.swing.JComponent; -import javax.swing.JPopupMenu; -import javax.swing.JWindow; -import javax.swing.SwingUtilities; +import com.fr.stable.StringUtils; +import javax.swing.*; import javax.swing.event.MouseInputAdapter; -import java.awt.Color; -import java.awt.Container; -import java.awt.Cursor; -import java.awt.Rectangle; +import java.awt.*; import java.awt.event.MouseEvent; /** @@ -158,7 +149,7 @@ public class EditingMouseListener extends MouseInputAdapter { if (e.getButton() == MouseEvent.BUTTON1) { Direction dir = selectionModel.getDirectionAt(e); - if (!BaseUtils.isAuthorityEditing()) { + if (!DesignerMode.isAuthorityEditing()) { stateModel.setDirection(dir); } @@ -272,7 +263,7 @@ public class EditingMouseListener extends MouseInputAdapter { public void mouseMoved(MouseEvent e) { XCreator component = designer.getComponentAt(e); - setCoverPaneNotDisplay(e, false); + setCoverPaneNotDisplay(component, e, false); if (processTopLayoutMouseMove(component, e)) { return; @@ -297,7 +288,7 @@ public class EditingMouseListener extends MouseInputAdapter { if (designer.isDrawLineMode() && stateModel.getDirection() == Location.outer) { designer.updateDrawLineMode(e); } - if (!BaseUtils.isAuthorityEditing()) { + if (!DesignerMode.isAuthorityEditing()) { stateModel.setDirection(dir); } @@ -325,23 +316,42 @@ public class EditingMouseListener extends MouseInputAdapter { designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } } - xElementCase.setHelpBtnOnFocus(false); - if (xElementCase.getCoverPane().getComponentCount() > 1) { - JComponent button1 = (JComponent) xElementCase.getCoverPane().getComponent(1); - int minX1 = button1.getX() + getParentPositionX(component, 0) - designer.getArea().getHorizontalValue(); - int minY1 = button1.getY() + getParentPositionY(component, 0) - designer.getArea().getVerticalValue(); - if (e.getX() + GAP - xElementCase.getInsets().left > minX1 && e.getX() - GAP - xElementCase.getInsets().left < minX1 + button1.getWidth()) { - if (e.getY() + GAP - xElementCase.getInsets().top > minY1 && e.getY() - GAP - xElementCase.getInsets().top < minY1 + button1.getHeight()) { + setHelpBtnFocus(e, xElementCase); + } + + private void setHelpBtnFocus(MouseEvent e, XCreator component) { + component.setHelpBtnOnFocus(false); + if (component.getCoverPane() != null) { + if (component.getCoverPane().getComponentCount() > 1) { + JComponent button1 = (JComponent) component.getCoverPane().getComponent(1); + int minX1 = button1.getX() + getParentPositionX(component, 0) - designer.getArea().getHorizontalValue(); + int minY1 = button1.getY() + getParentPositionY(component, 0) - designer.getArea().getVerticalValue(); + if (e.getX() + GAP - component.getInsets().left > minX1 && e.getX() - GAP - component.getInsets().left < minX1 + button1.getWidth()) { + if (e.getY() + GAP - component.getInsets().top > minY1 && e.getY() - GAP - component.getInsets().top < minY1 + button1.getHeight()) { + designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + component.setHelpBtnOnFocus(true); + } + } + } + component.displayCoverPane(true); + component.setDirections(Direction.TOP_BOTTOM_LEFT_RIGHT); + } else { + //没有帮助信息时,不显示帮助图标 + if (StringUtils.isEmpty(component.toData().getDescription())) { + return; + } + int minX1 = getParentPositionX(component, component.getX()) + component.getWidth() - ShareConstants.SHARE_EL_CONTROL_BUTTON_HW - designer.getArea().getHorizontalValue(); + int minY1 = getParentPositionY(component, component.getY()) - designer.getArea().getVerticalValue(); + if (e.getX() + GAP - component.getInsets().left > minX1 && e.getX() - GAP - component.getInsets().left < minX1 + ShareConstants.SHARE_EL_CONTROL_BUTTON_HW) { + if (e.getY() + GAP - component.getInsets().top > minY1 && e.getY() - GAP - component.getInsets().top < minY1 + ShareConstants.SHARE_EL_CONTROL_BUTTON_HW) { designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - xElementCase.setHelpBtnOnFocus(true); + component.setHelpBtnOnFocus(true); } } } - xElementCase.displayCoverPane(true); - xElementCase.setDirections(Direction.TOP_BOTTOM_LEFT_RIGHT); } - private void setCoverPaneNotDisplay(MouseEvent e, boolean isLinkedHelpDialog) { + private void setCoverPaneNotDisplay(XCreator component, MouseEvent e, boolean isLinkedHelpDialog) { if (xElementCase != null) { int x = getParentPositionX(xElementCase, 0) - designer.getArea().getHorizontalValue(); int y = getParentPositionY(xElementCase, 0) - designer.getArea().getVerticalValue(); @@ -349,15 +359,16 @@ public class EditingMouseListener extends MouseInputAdapter { if (rect.contains(e.getPoint())) { return; } - if (isLinkedHelpDialog) { - xElementCase.destroyHelpDialog(); - } + xElementCase.displayCoverPane(false); } if (xChartEditor != null) { xChartEditor.displayCoverPane(false); } - + if (isLinkedHelpDialog) { + component.destroyHelpDialog(); + } + component.displayCoverPane(false); if (xTopLayoutContainer != null) { xTopLayoutContainer.setMouseEnter(false); } @@ -383,6 +394,7 @@ public class EditingMouseListener extends MouseInputAdapter { designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } } + setHelpBtnFocus(e, xTopLayoutContainer); return true; } } @@ -403,8 +415,7 @@ public class EditingMouseListener extends MouseInputAdapter { designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } } - xChartEditor.displayCoverPane(true); - xChartEditor.setDirections(Direction.TOP_BOTTOM_LEFT_RIGHT); + setHelpBtnFocus(e, xChartEditor); designer.repaint(); } } @@ -425,9 +436,12 @@ public class EditingMouseListener extends MouseInputAdapter { * @param e 鼠标事件 */ public void mouseDragged(MouseEvent e) { - if (BaseUtils.isAuthorityEditing()) { + if (DesignerMode.isAuthorityEditing()) { return; } + if ((e.isShiftDown() || InputEventBaseOnOS.isControlDown(e)) && !stateModel.isSelecting()) { + stateModel.startSelecting(e); + } // 如果当前是左键拖拽状态,拖拽组件 if (stateModel.dragable()) { if (SwingUtilities.isRightMouseButton(e)) { @@ -571,12 +585,9 @@ public class EditingMouseListener extends MouseInputAdapter { * @param e 鼠标事件 */ public void mouseExited(MouseEvent e) { - if (designer.getCursor().getType() != Cursor.DEFAULT_CURSOR) { + if (designer.getCursor().getType() != Cursor.DEFAULT_CURSOR && !(e.isShiftDown() || InputEventBaseOnOS.isControlDown(e))) { designer.setCursor(Cursor.getDefaultCursor()); } - - setCoverPaneNotDisplay(e, true); - cancelPromptWidgetForbidEnter(); } diff --git a/designer-form/src/com/fr/design/widget/ui/designer/mobile/BodyMobileDefinePane.java b/designer-form/src/com/fr/design/widget/ui/designer/mobile/BodyMobileDefinePane.java new file mode 100644 index 000000000..394a59791 --- /dev/null +++ b/designer-form/src/com/fr/design/widget/ui/designer/mobile/BodyMobileDefinePane.java @@ -0,0 +1,124 @@ +package com.fr.design.widget.ui.designer.mobile; + +import com.fr.design.designer.beans.events.DesignerEvent; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.foldablepane.UIExpandablePane; +import com.fr.design.gui.frpane.AttributeChangeListener; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.FormDesigner; +import com.fr.design.mainframe.MobileWidgetListPane; +import com.fr.design.mainframe.WidgetPropertyPane; +import com.fr.form.ui.container.WSortLayout; +import com.fr.general.Inter; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.lang.reflect.Method; + +/** + * Created by plough on 2018/2/1. + */ +public class BodyMobileDefinePane extends MobileWidgetDefinePane { + private XCreator bodyCreator; + private FormDesigner designer; + private AttributeChangeListener changeListener; + private UICheckBox appRelayoutCheck; + private MobileWidgetListPane mobileWidgetListPane; + + public BodyMobileDefinePane(XCreator xCreator) { + this.bodyCreator = xCreator; + } + + @Override + public void initPropertyGroups(Object source) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + this.add(getMobilePropertyPane(), BorderLayout.NORTH); + this.add(getMobileWidgetListPane(), BorderLayout.CENTER); + this.repaint(); + } + + // 手机属性 + private UIExpandablePane getMobilePropertyPane() { + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + appRelayoutCheck = new UICheckBox(Inter.getLocText("FR-Designer-App_ReLayout"), true); + appRelayoutCheck.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); + panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + panel.add(appRelayoutCheck); + + final JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panelWrapper.add(panel, BorderLayout.NORTH); + + return new UIExpandablePane(Inter.getLocText("FR-Designer_Properties_Mobile"), 280, 20, panelWrapper); + } + + // 控件顺序 + private UIExpandablePane getMobileWidgetListPane() { + mobileWidgetListPane = new MobileWidgetListPane(designer, (WSortLayout) bodyCreator.toData()); + mobileWidgetListPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 5, 0)); + JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panelWrapper.add(mobileWidgetListPane, BorderLayout.CENTER); + + return new UIExpandablePane(Inter.getLocText("FR-Designer_WidgetOrder"), 280, 20, panelWrapper); + } + + private void bindListeners2Widgets() { + reInitAllListeners(); + this.changeListener = new AttributeChangeListener() { + @Override + public void attributeChange() { + update(); + } + }; + } + + /** + * 后台初始化所有事件. + */ + private void reInitAllListeners() { + initListener(this); + } + + // body是否开启手机重布局 + private boolean isAppRelayout() { + boolean result = false; + try { + Method m = bodyCreator.toData().getClass().getMethod("isAppRelayout"); + result = (boolean)m.invoke(bodyCreator.toData()); + } catch (Exception e) { + // do nothing + } + return result; + } + + private void setAppRelayout(boolean appRelayoutSeleted) { + if (appRelayoutSeleted == isAppRelayout()) { + return; + } + try { + Method m = bodyCreator.toData().getClass().getMethod("setAppRelayout", boolean.class); + m.invoke(bodyCreator.toData(), appRelayoutSeleted); + } catch (Exception e) { + // do nothing + } + } + + @Override + public void populate(FormDesigner designer) { + this.designer = designer; + appRelayoutCheck.setSelected(isAppRelayout()); + + // 数据 populate 完成后,再设置监听 + this.bindListeners2Widgets(); + this.addAttributeChangeListener(changeListener); + } + + @Override + public void update() { + setAppRelayout(appRelayoutCheck.isSelected()); + mobileWidgetListPane.updateToDesigner(); + designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED); + } +} diff --git a/designer-form/src/com/fr/design/widget/ui/designer/mobile/ChartEditorDefinePane.java b/designer-form/src/com/fr/design/widget/ui/designer/mobile/ChartEditorDefinePane.java new file mode 100644 index 000000000..fe299bfaa --- /dev/null +++ b/designer-form/src/com/fr/design/widget/ui/designer/mobile/ChartEditorDefinePane.java @@ -0,0 +1,196 @@ +package com.fr.design.widget.ui.designer.mobile; + +import com.fr.base.mobile.ChartMobileAttrProvider; +import com.fr.base.mobile.ChartMobileFitAttrState; +import com.fr.base.mobile.ChartMobileFitAttrStateProvider; +import com.fr.design.constants.LayoutConstants; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XWAbsoluteBodyLayout; +import com.fr.design.designer.creator.XWAbsoluteLayout; +import com.fr.design.designer.properties.items.Item; +import com.fr.design.foldablepane.UIExpandablePane; +import com.fr.design.gui.frpane.AttributeChangeListener; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.FormDesigner; +import com.fr.design.mainframe.WidgetPropertyPane; +import com.fr.form.FormFunctionProcessor; +import com.fr.form.ui.BaseChartEditor; +import com.fr.form.ui.container.WFitLayout; +import com.fr.general.Inter; +import com.fr.plugin.ExtraClassManager; +import com.fr.stable.fun.FunctionProcessor; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/** + * Created by plough on 2018/1/18. + */ +public class ChartEditorDefinePane extends MobileWidgetDefinePane { + private static final Item[] ITEMS = { + new Item(ChartMobileFitAttrState.AUTO.description(), ChartMobileFitAttrState.AUTO), + new Item(ChartMobileFitAttrState.AREA.description(), ChartMobileFitAttrState.AREA), + new Item(ChartMobileFitAttrState.PROPORTION.description(), ChartMobileFitAttrState.PROPORTION) + }; + + private XCreator xCreator; // 当前选中控件的xCreator + private FormDesigner designer; // 当前设计器 + private UIComboBox zoomOutComboBox;// 缩小逻辑下拉框 + private AttributeChangeListener changeListener; + private UILabel tipLabel; + + public ChartEditorDefinePane(XCreator xCreator) { + this.xCreator = xCreator; + } + + @Override + public void initPropertyGroups(Object source) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + JPanel mobileSettingsPane; + if (isInAbsoluteLayout()) { + mobileSettingsPane = getUnavailableTipPane(Inter.getLocText("FR-Designer_Tip_Chart_Adaptivity_Unavailable_In_Absolute_Layout")); + } else if (!isAppRelayout()) { + mobileSettingsPane = getUnavailableTipPane(Inter.getLocText("FR-Designer_Tip_Chart_Adaptivity_Unavailable")); + } else { + mobileSettingsPane = getMobileSettingsPane(); + } + this.add(mobileSettingsPane, BorderLayout.NORTH); + this.repaint(); + } + + private boolean isInAbsoluteLayout() { + Container parent = xCreator.getParent(); + while (parent != null) { + if (parent instanceof XWAbsoluteLayout && !(parent instanceof XWAbsoluteBodyLayout)) { + return true; + } + parent = parent.getParent(); + } + return false; + } + + // body是否开启手机重布局 + private boolean isAppRelayout() { + return ((WFitLayout)designer.getRootComponent().toData()).isAppRelayout(); + } + + private JPanel getUnavailableTipPane(String tipText) { + JPanel panel = new JPanel(new BorderLayout()); + UILabel unavailableTipLabel = new UILabel(); + unavailableTipLabel.setText("" + tipText + ""); + unavailableTipLabel.setForeground(Color.gray); + panel.add(unavailableTipLabel, BorderLayout.NORTH); + return panel; + } + + private UIExpandablePane getMobileSettingsPane() { + initZoomOutComboBox(); + + tipLabel = new UILabel(); + tipLabel.setForeground(Color.gray); + updateTipLabel(); + + Component[][] components = new Component[][]{ + new Component[] {new UILabel(Inter.getLocText("FR-Designer_Zoom_In_Logic"), SwingConstants.LEFT), new UILabel(ChartMobileFitAttrState.PROPORTION.description())}, + new Component[] {new UILabel(Inter.getLocText("FR-Designer_Zoom_Out_Logic"), SwingConstants.LEFT), zoomOutComboBox}, + new Component[] {tipLabel, null} + }; + + double f = TableLayout.FILL; + double p = TableLayout.PREFERRED; + double[] rowSize = {p, p, p}; + double[] columnSize = {p,f}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}}; + final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 30, LayoutConstants.VGAP_LARGE); + panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + final JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panelWrapper.add(panel, BorderLayout.NORTH); + + return new UIExpandablePane(Inter.getLocText("FR-Designer_Chart_Adaptivity"), 280, 20, panelWrapper); + } + + private void initZoomOutComboBox() { + this.zoomOutComboBox = new UIComboBox(ITEMS); + } + + + private void updateTipLabel() { + ChartMobileFitAttrState fitAttrState = (ChartMobileFitAttrState) ((Item)zoomOutComboBox.getSelectedItem()).getValue(); + // 使用 html,可以自动换行 + tipLabel.setText("" + fitAttrState.tip() + ""); + } + + private void bindListeners2Widgets() { + reInitAllListeners(); + this.changeListener = new AttributeChangeListener() { + @Override + public void attributeChange() { + update(); + } + }; + } + + /** + * 后台初始化所有事件. + */ + private void reInitAllListeners() { + initListener(this); + } + + @Override + public void populate(FormDesigner designer) { + this.designer = designer; + + if (!isAppRelayout() || isInAbsoluteLayout()) { + return; + } + + BaseChartEditor chartEditor = (BaseChartEditor)xCreator.toData(); + ChartMobileFitAttrStateProvider zoomOutAttr = chartEditor.getMobileAttr().getZoomOutAttr(); + this.zoomOutComboBox.setSelectedItem(new Item(zoomOutAttr.description(), zoomOutAttr)); + updateTipLabel(); + + // 数据 populate 完成后,再设置监听 + this.bindListeners2Widgets(); + this.zoomOutComboBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + // 只响应选中事件 + if (e.getStateChange() != ItemEvent.SELECTED) { + return; + } + updateTipLabel(); + ChartMobileFitAttrState selectedAttr = (ChartMobileFitAttrState)((Item)e.getItem()).getValue(); + if (selectedAttr.getState() != ChartMobileFitAttrState.AUTO.getState()) { + // 功能埋点 + FunctionProcessor processor = ExtraClassManager.getInstance().getFunctionProcessor(); + if (processor != null) { + processor.recordFunction(FormFunctionProcessor.MOBILE_CHART_ADAPTIVITY); + } + } + } + }); + this.addAttributeChangeListener(changeListener); + } + + @Override + public void update() { + ChartMobileAttrProvider mobileAttr = ((BaseChartEditor)xCreator.toData()).getMobileAttr(); + mobileAttr.setZoomInAttr(ChartMobileFitAttrState.PROPORTION); + mobileAttr.setZoomOutAttr((ChartMobileFitAttrState)((Item)zoomOutComboBox.getSelectedItem()).getValue()); + DesignerContext.getDesignerFrame().getSelectedJTemplate().fireTargetModified(); // 触发设计器保存按钮亮起来 + } +} diff --git a/designer-form/src/com/fr/design/widget/ui/designer/mobile/MultiFileUploaderDefinePane.java b/designer-form/src/com/fr/design/widget/ui/designer/mobile/MultiFileUploaderDefinePane.java new file mode 100644 index 000000000..bdf206898 --- /dev/null +++ b/designer-form/src/com/fr/design/widget/ui/designer/mobile/MultiFileUploaderDefinePane.java @@ -0,0 +1,110 @@ +package com.fr.design.widget.ui.designer.mobile; + +import com.fr.base.mobile.FileUploadModeState; +import com.fr.base.mobile.MultiFileUploaderMobileAttr; +import com.fr.design.constants.LayoutConstants; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.properties.items.Item; +import com.fr.design.foldablepane.UIExpandablePane; +import com.fr.design.gui.frpane.AttributeChangeListener; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.FormDesigner; +import com.fr.form.ui.MultiFileEditor; +import com.fr.general.Inter; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Component; + +/** + * Created by plough on 2018/4/19. + */ +public class MultiFileUploaderDefinePane extends MobileWidgetDefinePane { + private static final Item[] ITEMS = { + new Item(Inter.getLocText("FR-Designer_Take_Photos_And_Choose_From_Album"), FileUploadModeState.TAKE_PHOTOS_AND_CHOOSE_FROM_ALBUM), + new Item(Inter.getLocText("FR-Designer_Only_Take_Photos"), FileUploadModeState.ONLY_TAKE_PHOTOS) + }; + + private XCreator xCreator; // 当前选中控件的xCreator + private UIComboBox uploadModeComboBox;// 上传方式下拉框 + + public MultiFileUploaderDefinePane(XCreator xCreator) { + this.xCreator = xCreator; + } + + @Override + public void initPropertyGroups(Object source) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + JPanel mobileSettingsPane; + mobileSettingsPane = getMobileSettingsPane(); + + this.add(mobileSettingsPane, BorderLayout.NORTH); + this.repaint(); + } + + private UIExpandablePane getMobileSettingsPane() { + initUploadModeComboBox(); + + // 以后可能会扩展,还是用 TableLayout 吧 + Component[][] components = new Component[][]{ + new Component[] {new UILabel(Inter.getLocText("FR-Designer_Upload_Mode"), SwingConstants.LEFT), uploadModeComboBox} + }; + + double f = TableLayout.FILL; + double p = TableLayout.PREFERRED; + double[] rowSize = {p}; + double[] columnSize = {p,f}; + int[][] rowCount = {{1, 1}}; + final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 30, LayoutConstants.VGAP_LARGE); + panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + final JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panelWrapper.add(panel, BorderLayout.NORTH); + + return new UIExpandablePane(Inter.getLocText("FR-Designer_Terminal"), 280, 20, panelWrapper); + } + + private void initUploadModeComboBox() { + this.uploadModeComboBox = new UIComboBox(ITEMS); + } + + private void bindListeners2Widgets() { + reInitAllListeners(); + AttributeChangeListener changeListener = new AttributeChangeListener() { + @Override + public void attributeChange() { + update(); + } + }; + this.addAttributeChangeListener(changeListener); + } + + /** + * 后台初始化所有事件. + */ + private void reInitAllListeners() { + initListener(this); + } + + @Override + public void populate(FormDesigner designer) { + MultiFileUploaderMobileAttr mobileAttr = ((MultiFileEditor)xCreator.toData()).getMobileAttr(); + FileUploadModeState fileUploadModeState = mobileAttr.getFileUploadModeState(); + uploadModeComboBox.setSelectedIndex(fileUploadModeState.getState()); + // 数据 populate 完成后,再设置监听 + this.bindListeners2Widgets(); + } + + @Override + public void update() { + MultiFileUploaderMobileAttr mobileAttr = ((MultiFileEditor)xCreator.toData()).getMobileAttr(); + mobileAttr.setFileUploadModeState((FileUploadModeState) ((Item)uploadModeComboBox.getSelectedItem()).getValue()); + DesignerContext.getDesignerFrame().getSelectedJTemplate().fireTargetModified(); // 触发设计器保存按钮亮起来 + } +} diff --git a/designer-form/src/com/fr/design/widget/ui/designer/mobile/ParaMobileDefinePane.java b/designer-form/src/com/fr/design/widget/ui/designer/mobile/ParaMobileDefinePane.java new file mode 100644 index 000000000..a6910391c --- /dev/null +++ b/designer-form/src/com/fr/design/widget/ui/designer/mobile/ParaMobileDefinePane.java @@ -0,0 +1,81 @@ +package com.fr.design.widget.ui.designer.mobile; + +import com.fr.design.designer.beans.events.DesignerEvent; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.foldablepane.UIExpandablePane; +import com.fr.design.gui.frpane.AttributeChangeListener; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.FormDesigner; +import com.fr.design.mainframe.MobileWidgetListPane; +import com.fr.design.mainframe.WidgetPropertyPane; +import com.fr.form.ui.container.WSortLayout; +import com.fr.general.Inter; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; + +/** + * Created by plough on 2018/2/5. + */ +public class ParaMobileDefinePane extends MobileWidgetDefinePane { + private XCreator paraCreator; + private FormDesigner designer; + private AttributeChangeListener changeListener; + private MobileWidgetListPane mobileWidgetListPane; + + public ParaMobileDefinePane(XCreator xCreator) { + this.paraCreator = xCreator; + } + + @Override + public void initPropertyGroups(Object source) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + this.add(getMobileWidgetListPane(), BorderLayout.CENTER); + this.repaint(); + } + + // 控件顺序 + private UIExpandablePane getMobileWidgetListPane() { + mobileWidgetListPane = new MobileWidgetListPane(designer, (WSortLayout) paraCreator.toData()); + mobileWidgetListPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 5, 0)); + JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panelWrapper.add(mobileWidgetListPane, BorderLayout.CENTER); + + return new UIExpandablePane(Inter.getLocText("FR-Designer_WidgetOrder"), 280, 20, panelWrapper); + } + + private void bindListeners2Widgets() { + reInitAllListeners(); + this.changeListener = new AttributeChangeListener() { + @Override + public void attributeChange() { + update(); + } + }; + } + + /** + * 后台初始化所有事件. + */ + private void reInitAllListeners() { + initListener(this); + } + + + @Override + public void populate(FormDesigner designer) { + this.designer = designer; + + // 设置监听 + this.bindListeners2Widgets(); + this.addAttributeChangeListener(changeListener); + } + + @Override + public void update() { + mobileWidgetListPane.updateToDesigner(); + designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED); + } +} diff --git a/designer-realize/src/com/fr/design/actions/report/ReportMobileAttrAction.java b/designer-realize/src/com/fr/design/actions/report/ReportMobileAttrAction.java index 3813af30c..f6acfb251 100644 --- a/designer-realize/src/com/fr/design/actions/report/ReportMobileAttrAction.java +++ b/designer-realize/src/com/fr/design/actions/report/ReportMobileAttrAction.java @@ -1,5 +1,6 @@ package com.fr.design.actions.report; +import com.fr.base.iofileattr.MobileOnlyTemplateAttrMark; import com.fr.design.actions.JWorkBookAction; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.DialogActionAdapter; @@ -7,6 +8,7 @@ import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.JWorkBook; import com.fr.design.menu.MenuKeySet; import com.fr.design.report.mobile.ReportMobileAttrPane; +import com.fr.file.FILE; import com.fr.general.IOUtils; import com.fr.general.Inter; import com.fr.main.TemplateWorkBook; @@ -53,14 +55,26 @@ public class ReportMobileAttrAction extends JWorkBookAction{ @Override public void doOk() { ElementCaseMobileAttr elementCaseMobileAttr = mobileAttrPane.updateBean(); - wbTpl.setReportMobileAttr(elementCaseMobileAttr); - jwb.fireTargetModified(); - if (elementCaseMobileAttr.isMobileCanvasSize()) { - FunctionProcessor processor = ExtraClassManager.getInstance().getFunctionProcessor(); - if (processor != null) { - processor.recordFunction(ReportFunctionProcessor.MOBILE_TEMPLATE_CPT); + if (elementCaseMobileAttr.isMobileCanvasSize() && wbTpl.getAttrMark(MobileOnlyTemplateAttrMark.XML_TAG) == null) { + // 如果是老模板,选择手机专属之后需要另存为 + FILE editingFILE = jwb.getEditingFILE(); + if (editingFILE != null && editingFILE.exists()) { + String fileName = editingFILE.getName().substring(0, editingFILE.getName().length() - jwb.suffix().length()) + "_mobile"; + if (!jwb.saveAsTemplate(true, fileName)) { + return; // 不激活保存按钮 + } } + // 放到后面。如果提前 return 了,则仍然处于未设置状态,不要添加 + wbTpl.addAttrMark(new MobileOnlyTemplateAttrMark()); + } + // 记录功能点 + FunctionProcessor processor = ExtraClassManager.getInstance().getFunctionProcessor(); + if (processor != null) { + processor.recordFunction(ReportFunctionProcessor.MOBILE_TEMPLATE_CPT); } + // 设置移动端属性并刷新界面 + wbTpl.setReportMobileAttr(elementCaseMobileAttr); // 会同时修改页面设置,放到最后 + jwb.fireTargetModified(); } }); dialog.setVisible(true); diff --git a/designer-realize/src/com/fr/design/mainframe/CellWidgetPropertyPane.java b/designer-realize/src/com/fr/design/mainframe/CellWidgetPropertyPane.java index 9d311c310..2da57a7a7 100644 --- a/designer-realize/src/com/fr/design/mainframe/CellWidgetPropertyPane.java +++ b/designer-realize/src/com/fr/design/mainframe/CellWidgetPropertyPane.java @@ -107,17 +107,22 @@ public class CellWidgetPropertyPane extends BasicPane { } final CellSelection finalCS = (CellSelection) ePane.getSelection(); final TemplateElementCase tplEC = ePane.getEditingElementCase(); + final Widget cellWidget = cellEditorDefPane.update(); if(finalCS.isSelectedOneCell(ePane)){ if(tplEC.getTemplateCellElement(cellElement.getColumn(), cellElement.getRow())== null){//cellElement未加入到report中时要添加进去 tplEC.addCellElement(cellElement); } - setCellWidget(cellElement); + setCellWidget(cellWidget, cellElement); }else{ ReportActionUtils.actionIterateWithCellSelection(finalCS, tplEC, new ReportActionUtils.IterAction() { public void dealWith(CellElement editCellElement) { // p:最后把这个cellEditorDef设置到CellGUIAttr. TemplateCellElement templateCellElement = (TemplateCellElement) editCellElement; - setCellWidget(templateCellElement); + try { + setCellWidget((Widget)cellWidget.clone(), templateCellElement); + } catch (CloneNotSupportedException e) { + FRContext.getLogger().error("InternalError: " + e.getMessage()); + } } }); } @@ -126,8 +131,7 @@ public class CellWidgetPropertyPane extends BasicPane { } } - private void setCellWidget(TemplateCellElement cellElement){ - Widget cellWidget = cellEditorDefPane.update(); + private void setCellWidget(Widget cellWidget, TemplateCellElement cellElement){ if (cellWidget instanceof NoneWidget) { cellElement.setWidget(null); } else { diff --git a/designer-realize/src/com/fr/design/webattr/EditToolBar.java b/designer-realize/src/com/fr/design/webattr/EditToolBar.java index 2c2852d9e..978d96db6 100644 --- a/designer-realize/src/com/fr/design/webattr/EditToolBar.java +++ b/designer-realize/src/com/fr/design/webattr/EditToolBar.java @@ -31,19 +31,31 @@ import com.fr.form.ui.WidgetInfoConfig; import com.fr.general.Background; import com.fr.general.Inter; import com.fr.report.web.button.Export; -import com.fr.report.web.button.PDFPrint; -import com.fr.report.web.button.Print; import com.fr.report.web.button.write.AppendColumnRow; import com.fr.report.web.button.write.Submit; import com.fr.stable.ArrayUtils; import com.fr.stable.StringUtils; -import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.DefaultListCellRenderer; +import javax.swing.DefaultListModel; +import javax.swing.ImageIcon; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.ListCellRenderer; +import javax.swing.SpinnerNumberModel; +import javax.swing.SwingUtilities; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; @@ -320,7 +332,8 @@ public class EditToolBar extends BasicPane { private CardLayout card; private JPanel centerPane; private UICheckBox icon, text, pdf, excelP, excelO, excelS, image, word, - flashPrint, pdfPrint, appletPrint, serverPrint, isPopup, isVerify, failSubmit, isCurSheet; + isPopup, isVerify, failSubmit, isCurSheet, excelImClean, + excelImCover, excelImAppend, excelImCust; private UIBasicSpinner count; private Widget widget; private UITextField nameField; @@ -381,9 +394,7 @@ public class EditToolBar extends BasicPane { centerPane.setLayout(card); centerPane.add("custom", getCustomPane()); centerPane.add("export", getExport()); - centerPane.add("print", getPrint()); centerPane.add("none", none); - centerPane.add("pdfprint", getPdfPrintSetting()); // centerPane.add("editexcel", editExcel); centerPane.add(getCpane(), "appendcount"); centerPane.add(getSubmitPane(), "submit"); @@ -435,22 +446,6 @@ public class EditToolBar extends BasicPane { return export; } - private JPanel getPrint() { - JPanel print = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane(); - // print.setLayout(new BoxLayout(print, BoxLayout.Y_AXIS)); - flashPrint = new UICheckBox(Inter.getLocText("FR-Designer_Flash_Print")); - pdfPrint = new UICheckBox(Inter.getLocText("FR-Designer_PDF_Print")); - appletPrint = new UICheckBox(Inter.getLocText("FR-Designer_Applet_Print")); - serverPrint = new UICheckBox(Inter.getLocText("FR-Designer_Server_Print")); - print.add(flashPrint); - print.add(pdfPrint); - print.add(appletPrint); - print.add(serverPrint); - print.setBorder(BorderFactory.createTitledBorder(Inter.getLocText(new String[]{"Form-Button", "Property", "Set"}))); - return print; - } - - private JPanel getCpane() { JPanel appendCountPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane(); count = new UIBasicSpinner(new SpinnerNumberModel(1, 0, Integer.MAX_VALUE, 1)); @@ -463,16 +458,6 @@ public class EditToolBar extends BasicPane { } - private JPanel getPdfPrintSetting() { - // richer:pdf打印按钮设置 - JPanel pdfPrintSetting = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane(); - isPopup = new UICheckBox(Inter.getLocText("PDF-Print_isPopup")); - pdfPrintSetting.add(isPopup); - pdfPrintSetting.setBorder(BorderFactory.createTitledBorder(Inter.getLocText("PDF-Print_Setting"))); - return pdfPrintSetting; - } - - private JPanel getSubmitPane() { isVerify = new UICheckBox(Inter.getLocText("Verify-Data_Verify")); failSubmit = new UICheckBox(Inter.getLocText(new String[]{"Verify_Fail", "Still", "Submit"})); @@ -523,10 +508,6 @@ public class EditToolBar extends BasicPane { } if (widget instanceof Export) { populateExport(); - } else if (widget instanceof Print) { - populatePrint(); - } else if (widget instanceof PDFPrint) { - populatePDFPrint(); } else if (widget instanceof AppendColumnRow) { populateAppendColumnRow(); } else if (widget instanceof Submit) { @@ -581,21 +562,6 @@ public class EditToolBar extends BasicPane { this.isCurSheet.setSelected(submit.isOnlySubmitSelect()); } - private void populatePDFPrint(){ - card.show(centerPane, "pdfprint"); - PDFPrint pdfPrint = (PDFPrint) widget; - this.isPopup.setSelected(pdfPrint.isPopup()); - } - - private void populatePrint(){ - card.show(centerPane, "print"); - Print print = (Print) widget; - this.pdfPrint.setSelected(print.isPDFPrint()); - this.appletPrint.setSelected(print.isAppletPrint()); - this.flashPrint.setSelected(print.isFlashPrint()); - this.serverPrint.setSelected(print.isServerPrint()); - } - private void populateDefault(){ Button button = (Button) widget; this.icon.setSelected(button.isShowIcon()); @@ -612,11 +578,6 @@ public class EditToolBar extends BasicPane { public Widget update() { if (widget instanceof Export) { updateExport(); - } else if (widget instanceof Print) { - updatePrint(); - } else if (widget instanceof PDFPrint) { - PDFPrint pdfPrint = (PDFPrint) widget; - pdfPrint.setPopup(this.isPopup.isSelected()); } else if (widget instanceof AppendColumnRow) { ((AppendColumnRow) widget).setCount(((Integer) count.getValue()).intValue()); } else if (widget instanceof Submit) { @@ -650,14 +611,6 @@ public class EditToolBar extends BasicPane { submit.setOnlySubmitSelect(this.isCurSheet.isSelected()); } - private void updatePrint(){ - Print print = (Print) widget; - print.setAppletPrint(this.appletPrint.isSelected()); - print.setFlashPrint(this.flashPrint.isSelected()); - print.setPDFPrint(this.pdfPrint.isSelected()); - print.setServerPrint(this.serverPrint.isSelected()); - } - private void updateExport(){ Export export = (Export) widget; export.setPdfAvailable(this.pdf.isSelected()); diff --git a/designer-realize/src/com/fr/design/webattr/ToolBarPane.java b/designer-realize/src/com/fr/design/webattr/ToolBarPane.java index ebb3a696e..872b17008 100644 --- a/designer-realize/src/com/fr/design/webattr/ToolBarPane.java +++ b/designer-realize/src/com/fr/design/webattr/ToolBarPane.java @@ -7,9 +7,14 @@ import com.fr.design.gui.core.WidgetOption; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.form.ui.ToolBar; import com.fr.form.ui.Widget; - -import javax.swing.*; -import java.awt.*; +import com.fr.general.Inter; +import com.fr.report.web.annotation.OldPrintMethod; + +import javax.swing.BorderFactory; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; +import javax.swing.TransferHandler; +import java.awt.Component; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.MouseAdapter; @@ -19,6 +24,7 @@ import java.util.List; public class ToolBarPane extends BasicBeanPane { private FToolBar ftoolbar = new FToolBar(); + private boolean populateFinished = false; // 正在 populate 数据 public ToolBarPane() { super(); @@ -26,11 +32,11 @@ public class ToolBarPane extends BasicBeanPane { } - /** - * 添加鼠标监听 - * - * @param mouselistener 鼠标监听 - */ + /** + * 添加鼠标监听 + * + * @param mouselistener 鼠标监听 + */ public void addAuthorityListener(MouseListener mouselistener) { List list = ftoolbar.getButtonlist(); for (int i = 0; i < list.size(); i++) { @@ -44,9 +50,9 @@ public class ToolBarPane extends BasicBeanPane { this.add(button); } - /** - * 初始化组件 - */ + /** + * 初始化组件 + */ public void initComponent() { this.addMouseListener(listener); this.setLayout(FRGUIPaneFactory.createBoxFlowLayout()); @@ -54,9 +60,9 @@ public class ToolBarPane extends BasicBeanPane { this.setBorder(BorderFactory.createTitledBorder("")); } - /** - * 删除鼠标事件 - */ + /** + * 删除鼠标事件 + */ public void removeDefaultMouseListener() { this.removeMouseListener(listener); } @@ -70,15 +76,19 @@ public class ToolBarPane extends BasicBeanPane { this.ftoolbar.addButton(button); } - /** - * 添加组件 - * - * @param comp 组件 - * - * @return 被添加的组件 - */ + /** + * 添加组件 + * + * @param comp 组件 + * + * @return 被添加的组件 + */ public Component add(Component comp) { if (comp instanceof ToolBarButton) { + if (isPopulateFinished() && ((ToolBarButton) comp).getWidget().getClass().isAnnotationPresent(OldPrintMethod.class)) { + JOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(this), Inter.getLocText("FR-Designer_Use_New_Print_Tip")); + return comp; + } this.ftoolbar.addButton((ToolBarButton) comp); } return super.add(comp); @@ -128,15 +138,16 @@ public class ToolBarPane extends BasicBeanPane { @Override public void populateBean(ToolBar toolbar) { + setPopulateFinished(false); this.removeAll(); this.getFToolBar().clearButton(); for (int j = 0; j < toolbar.getWidgetSize(); j++) { Widget widget = toolbar.getWidget(j); WidgetOption no = WidgetOption.getToolBarButton(widget.getClass()); - if (no == null){ - //如果装了什么插件, 放到了工具栏上, 后来删除了插件, 模板里还存着之前的控件 - continue; - } + if (no == null){ + //如果装了什么插件, 放到了工具栏上, 后来删除了插件, 模板里还存着之前的控件 + continue; + } ToolBarButton button = new ToolBarButton(no.optionIcon(), widget); button.setNameOption(no); @@ -146,6 +157,7 @@ public class ToolBarPane extends BasicBeanPane { } this.getFToolBar().setBackground(toolbar.getBackground()); this.getFToolBar().setDefault(toolbar.isDefault()); + setPopulateFinished(true); } @Override @@ -171,6 +183,14 @@ public class ToolBarPane extends BasicBeanPane { } }; + private boolean isPopulateFinished() { + return populateFinished; + } + + private void setPopulateFinished(boolean populateFinished) { + this.populateFinished = populateFinished; + } + /* * 拖拽属性设置 From ebb917574c5b2d20ee475daa4498716a9d67470a Mon Sep 17 00:00:00 2001 From: CL <824983662@qq.com> Date: Thu, 7 Jun 2018 18:35:06 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=E7=9B=91?= =?UTF-8?q?=E5=90=AC=E6=9C=8D=E5=8A=A1=E7=AB=AF=E9=85=8D=E7=BD=AE=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../loghandler/socketio/DesignerSocketIO.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/designer-base/src/com/fr/design/mainframe/loghandler/socketio/DesignerSocketIO.java b/designer-base/src/com/fr/design/mainframe/loghandler/socketio/DesignerSocketIO.java index ac5a2ab01..51c1a8a85 100644 --- a/designer-base/src/com/fr/design/mainframe/loghandler/socketio/DesignerSocketIO.java +++ b/designer-base/src/com/fr/design/mainframe/loghandler/socketio/DesignerSocketIO.java @@ -1,5 +1,7 @@ package com.fr.design.mainframe.loghandler.socketio; +import com.fr.config.ConfigEvent; +import com.fr.config.Configuration; import com.fr.core.env.EnvConfig; import com.fr.core.env.EnvConstants; import com.fr.core.env.EnvContext; @@ -79,6 +81,18 @@ public class DesignerSocketIO { socketIO = Optional.of(IO.socket(new URI(uri))); socketIO.get().on(EnvConstants.WS_LOGRECORD, printLog); + socketIO.get().on(EnvConstants.CONFIG, new Emitter.Listener() { + @Override + public void call(Object... objects) { + if (objects == null || objects.length != 1) { + throw new IllegalArgumentException("config should have only one param"); + } + Object param = objects[0]; + if (param instanceof Class) { + EventDispatcher.fire(ConfigEvent.EDIT, (Class) param); + } + } + }); socketIO.get().connect(); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); From 7e748899f35a281486a10bf1b0f4d6758e5fb7e8 Mon Sep 17 00:00:00 2001 From: vito Date: Thu, 7 Jun 2018 18:37:09 +0800 Subject: [PATCH 7/9] =?UTF-8?q?REPORT-8393=20=E6=8F=92=E4=BB=B6=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=95=8C=E9=9D=A2=E6=97=A0=E6=B3=95=E5=90=AF=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- designer-realize/src/com/fr/start/fx/SplashFx.java | 3 ++- .../src/com/fr/start/fx/SplashFxWindow.java | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/designer-realize/src/com/fr/start/fx/SplashFx.java b/designer-realize/src/com/fr/start/fx/SplashFx.java index 7970e204f..aef6d81b2 100644 --- a/designer-realize/src/com/fr/start/fx/SplashFx.java +++ b/designer-realize/src/com/fr/start/fx/SplashFx.java @@ -23,6 +23,7 @@ public class SplashFx implements SplashStrategy { @Override public void show() { + Platform.setImplicitExit(false); SERVICE.execute(new Runnable() { @Override public void run() { @@ -34,7 +35,7 @@ public class SplashFx implements SplashStrategy { @Override public void hide() { - Platform.exit(); + fxWindow.close(); } @Override diff --git a/designer-realize/src/com/fr/start/fx/SplashFxWindow.java b/designer-realize/src/com/fr/start/fx/SplashFxWindow.java index 486ba69b6..451fad60d 100644 --- a/designer-realize/src/com/fr/start/fx/SplashFxWindow.java +++ b/designer-realize/src/com/fr/start/fx/SplashFxWindow.java @@ -115,6 +115,19 @@ public class SplashFxWindow extends Application { primaryStage.show(); } + public void close() { + Platform.runLater(new Runnable() { + @Override + public void run() { + try { + ((Stage) moduleInfo.getScene().getWindow()).close(); + } catch (Exception e) { + FRContext.getLogger().error(e.getMessage(), e); + } + } + }); + } + /** * 更新模块信息 * From d3a7929afbbbd73bf262adaa67f6ad77fd326d7d Mon Sep 17 00:00:00 2001 From: ju Date: Thu, 7 Jun 2018 21:22:01 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E6=97=A0JIRA=E4=BB=BB=E5=8A=A1=20=E5=85=88?= =?UTF-8?q?=E5=8A=A0=E5=9B=9E=E6=9D=A5=E6=89=93=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../loghandler/socketio/DesignerSocketIO.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/designer-base/src/com/fr/design/mainframe/loghandler/socketio/DesignerSocketIO.java b/designer-base/src/com/fr/design/mainframe/loghandler/socketio/DesignerSocketIO.java index 51c1a8a85..2da090c1e 100644 --- a/designer-base/src/com/fr/design/mainframe/loghandler/socketio/DesignerSocketIO.java +++ b/designer-base/src/com/fr/design/mainframe/loghandler/socketio/DesignerSocketIO.java @@ -81,18 +81,18 @@ public class DesignerSocketIO { socketIO = Optional.of(IO.socket(new URI(uri))); socketIO.get().on(EnvConstants.WS_LOGRECORD, printLog); - socketIO.get().on(EnvConstants.CONFIG, new Emitter.Listener() { - @Override - public void call(Object... objects) { - if (objects == null || objects.length != 1) { - throw new IllegalArgumentException("config should have only one param"); - } - Object param = objects[0]; - if (param instanceof Class) { - EventDispatcher.fire(ConfigEvent.EDIT, (Class) param); - } - } - }); +// socketIO.get().on(EnvConstants.CONFIG, new Emitter.Listener() { +// @Override +// public void call(Object... objects) { +// if (objects == null || objects.length != 1) { +// throw new IllegalArgumentException("config should have only one param"); +// } +// Object param = objects[0]; +// if (param instanceof Class) { +// EventDispatcher.fire(ConfigEvent.EDIT, (Class) param); +// } +// } +// }); socketIO.get().connect(); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); From e8c55241c3d7cf3c3e29bb93d76de4fd2a34e15a Mon Sep 17 00:00:00 2001 From: plough Date: Thu, 7 Jun 2018 22:18:13 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E6=97=A0JIRA=E4=BB=BB=E5=8A=A1=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=96=E8=AF=91=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/com/fr/design/mainframe/FormModelAdapter.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/designer-form/src/com/fr/design/mainframe/FormModelAdapter.java b/designer-form/src/com/fr/design/mainframe/FormModelAdapter.java index 0ecedacaf..65e9d41d8 100644 --- a/designer-form/src/com/fr/design/mainframe/FormModelAdapter.java +++ b/designer-form/src/com/fr/design/mainframe/FormModelAdapter.java @@ -5,7 +5,11 @@ import com.fr.design.DesignModelAdapter; import com.fr.design.file.HistoryTemplateListPane; import com.fr.form.main.Form; import com.fr.form.main.WidgetGatherAdapter; -import com.fr.form.ui.*; +import com.fr.form.ui.BaseChartEditor; +import com.fr.form.ui.DataControl; +import com.fr.form.ui.ElementCaseEditor; +import com.fr.form.ui.MultiFileEditor; +import com.fr.form.ui.Widget; import com.fr.stable.js.WidgetName; import java.util.ArrayList; @@ -85,7 +89,7 @@ public class FormModelAdapter extends DesignModelAdapter { } public void dealWith(Widget widget) { - boolean isSupportAsHypelink = widget.acceptType(ElementCaseEditor.class) || widget.acceptType(ChartEditorProvider.class); + boolean isSupportAsHypelink = widget.acceptType(ElementCaseEditor.class) || widget.acceptType(BaseChartEditor.class); //可以超链的对象不包含本身; 目前只有图表和报表块可以 // bug66182 删了条件:!ComparatorUtils.equals(editingECName, widget.getWidgetName()) 让当前表单对象可以选到自己 if (isSupportAsHypelink){