Browse Source

REPORT-8357 .0之前开发的功能与bug patch到10.0 图片压缩

master
zack 6 years ago
parent
commit
f169fb0b0f
  1. 12
      designer-base/src/com/fr/design/DesignerEnvManager.java
  2. 154
      designer-base/src/com/fr/design/gui/frpane/ImgChooseWrapper.java
  3. 38
      designer-base/src/com/fr/design/mainframe/backgroundpane/ImageBackgroundQuickPane.java
  4. 514
      designer-base/src/com/fr/design/mainframe/backgroundpane/ImagePreviewPane.java
  5. 196
      designer-base/src/com/fr/design/style/background/image/ExpandFileChooser.java
  6. 31
      designer-base/src/com/fr/design/style/background/image/ImageFileChooser.java
  7. 118
      designer-base/src/com/fr/design/style/background/image/ImagePreviewPane.java
  8. 40
      designer-base/src/com/fr/design/style/background/image/ImagePreviewer.java
  9. 16
      designer-base/src/com/fr/design/style/background/image/ImageSelectPane.java
  10. 56
      designer-base/src/com/fr/design/style/background/impl/ImageBackgroundPane.java
  11. 13
      designer-base/src/com/fr/design/style/background/impl/ImageBackgroundPane4Browser.java
  12. 22
      designer-base/src/com/fr/design/style/background/impl/ImageButtonBackgroundPane.java
  13. 285
      designer-base/src/com/fr/design/utils/ImageUtils.java
  14. 53
      designer-realize/src/com/fr/design/headerfooter/ImagePane.java

12
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<SwingWorker> mapWorkerList = new ArrayList<SwingWorker>();
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;
}
}

154
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<Void, Void> 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<Void, Void> getImageWorker() {
return imageWorker;
}
public void setImageWorker(SwingWorker<Void, Void> 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<Void, Void>() {
@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"));
}
}
}

38
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();
}

514
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<ChangeListener> changeListenerList = new ArrayList<ChangeListener>();
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<ChangeListener> changeListenerList = new ArrayList<ChangeListener>();
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 <code>preferredSize</code> of a <code>JViewport</code> whose
* view is this <code>Scrollable</code>
*/
@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.
* <p/>
* 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 <code>SwingConstants.VERTICAL</code> or
* <code>SwingConstants.HORIZONTAL</code>
* @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.
* <p/>
* 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 <code>SwingConstants.VERTICAL</code> or
* <code>SwingConstants.HORIZONTAL</code>
* @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 <code>preferredSize</code> of a <code>JViewport</code> whose
* view is this <code>Scrollable</code>
*/
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
/**
* Returns true if a viewport should always force the width of this
* <code>Scrollable</code> 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
* <code>Scrollable</code> whose ancestor is a <code>JScrollPane</code>
* effectively disables horizontal scrolling.
* <p/>
* Scrolling containers, like <code>JViewport</code>, will use this method
* each time they are validated.
*
* @return true if a viewport should force the <code>Scrollable</code>s
* 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.
* <p/>
* 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 <code>SwingConstants.VERTICAL</code> or
* <code>SwingConstants.HORIZONTAL</code>
* @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
* <code>Scrollable</code> 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.
* <p/>
* Scrolling containers, like <code>JViewport</code>, 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.
* <p/>
* 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 <code>SwingConstants.VERTICAL</code> or
* <code>SwingConstants.HORIZONTAL</code>
* @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
* <code>Scrollable</code> 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
* <code>Scrollable</code> whose ancestor is a <code>JScrollPane</code>
* effectively disables horizontal scrolling.
* <p/>
* Scrolling containers, like <code>JViewport</code>, will use this method
* each time they are validated.
*
* @return true if a viewport should force the <code>Scrollable</code>s
* 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
* <code>Scrollable</code> 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.
* <p/>
* Scrolling containers, like <code>JViewport</code>, 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;
}
}

196
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) {
}
}
}

31
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.
* <p/>D:\finereport\develop\code\test\TestCase\WEB-INF\reportlets\TestCase\01903.cpt
* <p>
* Extensions are of the type ".foo", which is typically found on
* Windows and Unix boxes, but not on Macinthosh. Case is ignored.
* <p/>

118
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<ChangeListener> changeListenerList = new ArrayList<ChangeListener>();
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 <code>preferredSize</code> of a <code>JViewport</code>
* whose view is this <code>Scrollable</code>
* whose view is this <code>Scrollable</code>
*/
@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 <code>Scrollable</code>s
* 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;
}
}

40
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();
}

16
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);
}
}
};

56
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;
}
}

13
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,
});
}
}

22
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());
}
}

285
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<ImageWriter> 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<ImageReader> 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);
}
}

53
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);
}
};
}
Loading…
Cancel
Save