Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
xy.reflect.ui.control.swing.plugin.ImageViewPlugin Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (C) 2018 OTK Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* The GNU General Public License allows you also to freely redistribute
* the libraries under the same license, if you provide the terms of the
* GNU General Public License with them and add the following
* copyright notice at the appropriate place (with a link to
* http://javacollection.net/reflectionui/ web site when possible).
******************************************************************************/
package xy.reflect.ui.control.swing.plugin;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.TitledBorder;
import xy.reflect.ui.ReflectionUI;
import xy.reflect.ui.control.DefaultFieldControlData;
import xy.reflect.ui.control.DefaultFieldControlInput;
import xy.reflect.ui.control.FieldControlDataProxy;
import xy.reflect.ui.control.IFieldControlData;
import xy.reflect.ui.control.IFieldControlInput;
import xy.reflect.ui.control.plugin.AbstractSimpleCustomizableFieldControlPlugin;
import xy.reflect.ui.control.swing.IAdvancedFieldControl;
import xy.reflect.ui.control.swing.plugin.FileBrowserPlugin.FileBrowser;
import xy.reflect.ui.control.swing.plugin.FileBrowserPlugin.FileBrowserConfiguration;
import xy.reflect.ui.control.swing.plugin.FileBrowserPlugin.FileNameFilterConfiguration;
import xy.reflect.ui.control.swing.plugin.FileBrowserPlugin.SelectionModeConfiguration;
import xy.reflect.ui.control.swing.renderer.SwingRenderer;
import xy.reflect.ui.info.menu.MenuModel;
import xy.reflect.ui.info.method.AbstractConstructorInfo;
import xy.reflect.ui.info.method.IMethodInfo;
import xy.reflect.ui.info.method.InvocationData;
import xy.reflect.ui.info.parameter.IParameterInfo;
import xy.reflect.ui.info.type.ITypeInfo;
import xy.reflect.ui.info.type.factory.InfoProxyFactory;
import xy.reflect.ui.info.type.source.JavaTypeInfoSource;
import xy.reflect.ui.info.type.source.SpecificitiesIdentifier;
import xy.reflect.ui.info.type.source.TypeInfoSourceProxy;
import xy.reflect.ui.util.ClassUtils;
import xy.reflect.ui.util.ReflectionUIError;
import xy.reflect.ui.util.SwingRendererUtils;
import xy.reflect.ui.util.component.AbstractControlButton;
import xy.reflect.ui.util.component.ControlPanel;
import xy.reflect.ui.util.component.ControlScrollPane;
import xy.reflect.ui.util.component.ImagePanel;
public class ImageViewPlugin extends AbstractSimpleCustomizableFieldControlPlugin {
@Override
public String getControlTitle() {
return "Image View";
}
@Override
protected boolean handles(Class javaType) {
return Image.class.isAssignableFrom(javaType);
}
@Override
public AbstractConfiguration getDefaultControlCustomization() {
return new ImageViewConfiguration();
}
@Override
public ImageView createControl(Object renderer, IFieldControlInput input) {
return new ImageView((SwingRenderer) renderer, input);
}
@Override
public boolean canDisplayDistinctNullValue() {
return false;
}
@Override
public IFieldControlData filterDistinctNullValueControlData(final Object renderer, IFieldControlData controlData) {
return new FieldControlDataProxy(controlData) {
@Override
public ITypeInfo getType() {
return new ImageTypeInfoProxyFactory(((SwingRenderer) renderer).getReflectionUI())
.wrapTypeInfo(super.getType());
}
};
}
protected static class ImageTypeInfoProxyFactory extends InfoProxyFactory {
protected ReflectionUI reflectionUI;
public ImageTypeInfoProxyFactory(ReflectionUI reflectionUI) {
this.reflectionUI = reflectionUI;
}
@Override
protected List getConstructors(ITypeInfo type) {
if (ImageConstructor.isCompatibleWith(type)) {
List result = new ArrayList();
result.add(new ImageConstructor(reflectionUI, type));
return result;
}
return super.getConstructors(type);
}
@Override
protected boolean isConcrete(ITypeInfo type) {
if (ImageConstructor.isCompatibleWith(type)) {
return true;
}
return super.isConcrete(type);
}
}
protected static class ImageConstructor extends AbstractConstructorInfo {
protected ReflectionUI reflectionUI;
protected ITypeInfo type;
protected ITypeInfo returnType;
public ImageConstructor(ReflectionUI reflectionUI, ITypeInfo type) {
this.reflectionUI = reflectionUI;
this.type = type;
}
@Override
public ITypeInfo getReturnValueType() {
if (returnType == null) {
returnType = reflectionUI.getTypeInfo(new TypeInfoSourceProxy(type.getSource()) {
@Override
public SpecificitiesIdentifier getSpecificitiesIdentifier() {
return null;
}
});
}
return returnType;
}
@Override
public List getParameters() {
return Collections.emptyList();
}
@Override
public Object invoke(Object parentObject, InvocationData invocationData) {
return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
}
public static boolean isCompatibleWith(ITypeInfo type) {
Class imageClass;
try {
imageClass = ClassUtils.getCachedClassforName(type.getName());
} catch (ClassNotFoundException e) {
return false;
}
return imageClass.isAssignableFrom(BufferedImage.class);
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
ImageConstructor other = (ImageConstructor) obj;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
@Override
public String toString() {
return "ImageConstructor [type=" + type + "]";
}
}
public static class ImageViewConfiguration extends AbstractConfiguration {
private static final long serialVersionUID = 1L;
public SizeConstraint sizeConstraint;
}
public enum ImageSizeUnit {
PIXELS, SCREEN_PERCENT
}
public static abstract class SizeConstraint extends AbstractConfiguration {
private static final long serialVersionUID = 1L;
public int canvasWidth = 100;
public int canvasHeight = 100;
public ImageSizeUnit unit = ImageSizeUnit.PIXELS;
public boolean scalingQualitHigh = false;;
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
if (unit == null) {
unit = ImageSizeUnit.PIXELS;
}
}
public abstract void configure(ImageView imageView, JPanel imagePanelContainer, ImagePanel imagePanel);
public abstract void updateImagePanel(ImageView imageView, ImagePanel imagePanel);
protected Dimension getSizeInPixels() {
if (unit == ImageSizeUnit.PIXELS) {
return new Dimension(canvasWidth, canvasHeight);
} else if (unit == ImageSizeUnit.SCREEN_PERCENT) {
Dimension screenSize = SwingRendererUtils.getDefaultScreenSize();
int width = Math.round((canvasWidth / 100f) * screenSize.width);
int height = Math.round((canvasHeight / 100f) * screenSize.height);
return new Dimension(width, height);
} else {
throw new ReflectionUIError();
}
}
}
public static class StretchingSizeConstraint extends SizeConstraint {
private static final long serialVersionUID = 1L;
@Override
public void configure(ImageView imageView, JPanel imagePanelContainer, ImagePanel imagePanel) {
Dimension size = getSizeInPixels();
imagePanel.setPreferredSize(size);
imagePanel.setMinimumSize(size);
imagePanel.setPreservingRatio(false);
imagePanel.setScalingQualitHigh(scalingQualitHigh);
imagePanelContainer.setLayout(new BorderLayout());
imagePanelContainer.add(imagePanel, BorderLayout.CENTER);
}
@Override
public void updateImagePanel(ImageView imageView, ImagePanel imagePanel) {
Image image = (Image) imageView.data.getValue();
imagePanel.setImage(image);
}
}
public static class ScalingSizeConstraint extends SizeConstraint {
private static final long serialVersionUID = 1L;
public boolean areaFilled = false;
@Override
public void configure(ImageView imageView, JPanel imagePanelContainer, ImagePanel imagePanel) {
Dimension size = getSizeInPixels();
imagePanel.setPreferredSize(size);
imagePanel.setMinimumSize(size);
imagePanel.setPreservingRatio(true);
imagePanel.setFillingAreaWhenPreservingRatio(areaFilled);
imagePanel.setScalingQualitHigh(scalingQualitHigh);
imagePanelContainer.setLayout(new BorderLayout());
imagePanelContainer.add(imagePanel, BorderLayout.CENTER);
}
@Override
public void updateImagePanel(ImageView imageView, ImagePanel imagePanel) {
Image image = (Image) imageView.data.getValue();
imagePanel.setImage(image);
}
}
public static class ScrollableSizeConstraint extends SizeConstraint {
private static final long serialVersionUID = 1L;
@Override
public void configure(ImageView imageView, JPanel imagePanelContainer, ImagePanel imagePanel) {
imagePanel.setPreservingRatio(true);
imagePanel.setFillingAreaWhenPreservingRatio(false);
imagePanel.setScalingQualitHigh(scalingQualitHigh);
JScrollPane scrollPane = new ControlScrollPane(
SwingRendererUtils.flowInLayout(imagePanel, GridBagConstraints.CENTER));
scrollPane.setBorder(null);
Dimension size = getSizeInPixels();
scrollPane.setPreferredSize(size);
scrollPane.setMinimumSize(size);
imagePanelContainer.setLayout(new BorderLayout());
imagePanelContainer.add(scrollPane, BorderLayout.CENTER);
}
@Override
public void updateImagePanel(ImageView imageView, ImagePanel imagePanel) {
imageView.updateImagePanelWithoutSizeConstraint(imageView, imagePanel);
}
}
public static class ZoomableSizeConstraint extends SizeConstraint {
private static final long serialVersionUID = 1L;
@Override
public void configure(final ImageView imageView, JPanel imagePanelContainer, final ImagePanel imagePanel) {
imagePanelContainer.setLayout(new BorderLayout());
imagePanel.setPreservingRatio(true);
imagePanel.setFillingAreaWhenPreservingRatio(false);
imagePanel.setScalingQualitHigh(scalingQualitHigh);
JPanel zoomPanel = new ControlPanel();
{
imagePanelContainer.add(SwingRendererUtils.flowInLayout(zoomPanel, GridBagConstraints.CENTER),
BorderLayout.NORTH);
zoomPanel.setBorder(BorderFactory.createTitledBorder(null,
imageView.swingRenderer.prepareStringToDisplay("Zoom"), TitledBorder.CENTER, TitledBorder.TOP));
if (imageView.data.getForegroundColor() != null) {
((TitledBorder) zoomPanel.getBorder())
.setTitleColor(SwingRendererUtils.getColor(imageView.data.getForegroundColor()));
}
if (imageView.data.getBorderColor() != null) {
((TitledBorder) zoomPanel.getBorder()).setBorder(BorderFactory
.createLineBorder(SwingRendererUtils.getColor(imageView.data.getBorderColor())));
}
final float ZOOM_CHANGE_FACTOR = 1.3f;
zoomPanel.setLayout(new FlowLayout());
JButton smallerButton = createZoomButton(imageView, "-");
{
zoomPanel.add(smallerButton);
smallerButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Dimension size = imagePanel.getSize();
size.width /= ZOOM_CHANGE_FACTOR;
size.height /= ZOOM_CHANGE_FACTOR;
imagePanel.setPreferredSize(size);
SwingRendererUtils.handleComponentSizeChange(imagePanel);
}
});
}
JButton biggerButton = createZoomButton(imageView, "+");
{
zoomPanel.add(biggerButton);
biggerButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Dimension size = imagePanel.getSize();
size.width *= ZOOM_CHANGE_FACTOR;
size.height *= ZOOM_CHANGE_FACTOR;
imagePanel.setPreferredSize(size);
SwingRendererUtils.handleComponentSizeChange(imagePanel);
}
});
}
}
imagePanel.setPreferredSize(getSizeInPixels());
JScrollPane scrollPane = new ControlScrollPane(
SwingRendererUtils.flowInLayout(imagePanel, GridBagConstraints.CENTER));
{
imagePanelContainer.add(scrollPane, BorderLayout.CENTER);
scrollPane.setBorder(null);
Dimension size = getSizeInPixels();
size.width += scrollPane.getHorizontalScrollBar().getPreferredSize().height;
size.height += scrollPane.getVerticalScrollBar().getPreferredSize().width;
scrollPane.setPreferredSize(size);
scrollPane.setMinimumSize(size);
}
}
protected JButton createZoomButton(final ImageView imageView, final String caption) {
return new AbstractControlButton() {
private static final long serialVersionUID = 1L;
@Override
public SwingRenderer getSwingRenderer() {
return imageView.swingRenderer;
}
@Override
public String retrieveCaption() {
return caption;
}
@Override
protected boolean isApplicationStyleButtonSpecific() {
return true;
}
};
}
@Override
public void updateImagePanel(ImageView imageView, ImagePanel imagePanel) {
Image image = (Image) imageView.data.getValue();
imagePanel.setImage(image);
}
}
public class ImageView extends ControlPanel implements IAdvancedFieldControl {
private static final long serialVersionUID = 1L;
protected SwingRenderer swingRenderer;
protected IFieldControlInput input;
protected IFieldControlData data;
protected Class numberClass;
protected ImagePanel imagePanel;
protected JPanel imagePanelContainer;
public ImageView(SwingRenderer swingRenderer, IFieldControlInput input) {
this.swingRenderer = swingRenderer;
this.input = input;
this.data = input.getControlData();
try {
this.numberClass = ClassUtils.getCachedClassforName(input.getControlData().getType().getName());
if (this.numberClass.isPrimitive()) {
this.numberClass = ClassUtils.primitiveToWrapperClass(numberClass);
}
} catch (ClassNotFoundException e1) {
throw new ReflectionUIError(e1);
}
setLayout(new BorderLayout());
imagePanelContainer = new ControlPanel();
add(SwingRendererUtils.flowInLayout(imagePanelContainer, GridBagConstraints.CENTER), BorderLayout.CENTER);
browseOnMousePressed(this);
refreshUI(true);
}
@Override
public boolean refreshUI(boolean refreshStructure) {
ImageViewConfiguration controlCustomization = (ImageViewConfiguration) loadControlCustomization(input);
if (refreshStructure) {
if (data.getCaption().length() > 0) {
setBorder(
BorderFactory.createTitledBorder(swingRenderer.prepareStringToDisplay(data.getCaption())));
if (data.getForegroundColor() != null) {
((TitledBorder) getBorder())
.setTitleColor(SwingRendererUtils.getColor(data.getForegroundColor()));
}
if (data.getBorderColor() != null) {
((TitledBorder) getBorder()).setBorder(
BorderFactory.createLineBorder(SwingRendererUtils.getColor(data.getBorderColor())));
}
} else {
setBorder(BorderFactory.createEmptyBorder());
}
if (!data.isGetOnly()) {
setBorder(
BorderFactory.createCompoundBorder(getBorder(), BorderFactory.createLoweredBevelBorder()));
}
imagePanelContainer.removeAll();
imagePanel = null;
}
if (imagePanel == null) {
imagePanel = createImagePanel();
if (controlCustomization.sizeConstraint == null) {
configureWithoutSizeConstraint(this, imagePanelContainer, imagePanel);
updateImagePanelWithoutSizeConstraint(this, imagePanel);
} else {
controlCustomization.sizeConstraint.configure(this, imagePanelContainer, imagePanel);
controlCustomization.sizeConstraint.updateImagePanel(this, imagePanel);
}
} else {
if (controlCustomization.sizeConstraint == null) {
updateImagePanelWithoutSizeConstraint(this, imagePanel);
} else {
controlCustomization.sizeConstraint.updateImagePanel(this, imagePanel);
}
}
imagePanel.getParent().invalidate();
SwingRendererUtils.handleComponentSizeChange(this);
return true;
}
protected void browseOnMousePressed(Component c) {
c.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (data.isGetOnly()) {
return;
}
try {
onBrowseImage();
} catch (Throwable t) {
ImageView.this.swingRenderer.handleExceptionsFromDisplayedUI(ImageView.this, t);
}
}
});
}
protected ImagePanel createImagePanel() {
ImagePanel result = new ImagePanel();
if (!data.isGetOnly()) {
browseOnMousePressed(result);
}
return result;
}
protected void onBrowseImage() {
final FileBrowserConfiguration fileBrowserConfiguration = new FileBrowserConfiguration();
fileBrowserConfiguration.selectionMode = SelectionModeConfiguration.FILES_ONLY;
fileBrowserConfiguration.actionTitle = "Load Image";
FileNameFilterConfiguration filter = new FileNameFilterConfiguration();
{
filter.description = "Images";
filter.extensions.addAll(Arrays.asList(ImageIO.getReaderFileSuffixes()));
fileBrowserConfiguration.fileNameFilters.add(filter);
}
final File[] imageFileHolder = new File[1];
final FileBrowserPlugin browserPlugin = new FileBrowserPlugin();
IFieldControlInput fileBrowserInput = new DefaultFieldControlInput(swingRenderer.getReflectionUI()) {
@Override
public IFieldControlData getControlData() {
return new DefaultFieldControlData(swingRenderer.getReflectionUI()) {
@Override
public Object getValue() {
return imageFileHolder[0];
}
@Override
public void setValue(Object value) {
imageFileHolder[0] = (File) value;
}
@Override
public ITypeInfo getType() {
return new InfoProxyFactory() {
@Override
protected Map getSpecificProperties(ITypeInfo type) {
Map result = super.getSpecificProperties(type);
result = new HashMap();
browserPlugin.storeControlCustomization(fileBrowserConfiguration, result);
return result;
}
}.wrapTypeInfo(swingRenderer.getReflectionUI()
.getTypeInfo(new JavaTypeInfoSource(File.class, null)));
}
};
}
};
FileBrowser browser = browserPlugin.createControl(swingRenderer, fileBrowserInput);
browser.openDialog(browser);
if (imageFileHolder[0] == null) {
return;
}
Image loadedImage;
try {
loadedImage = ImageIO.read(imageFileHolder[0]);
} catch (IOException e) {
throw new ReflectionUIError(
"Failed to load the image file '" + imageFileHolder[0] + "': " + e.toString(), e);
}
data.setValue(loadedImage);
}
@Override
public boolean displayError(String msg) {
return false;
}
@Override
public boolean showsCaption() {
return true;
}
protected void updateImagePanelWithoutSizeConstraint(ImageView imageView, ImagePanel imagePanel) {
Image image = (Image) data.getValue();
if (image != null) {
imagePanel.setImage(image);
Dimension size = new Dimension(image.getWidth(null), image.getHeight(null));
imagePanel.setPreferredSize(size);
imagePanel.setMinimumSize(size);
} else {
imagePanel.setImage(null);
imagePanel.setPreferredSize(null);
imagePanel.setMinimumSize(null);
}
}
protected void configureWithoutSizeConstraint(ImageView imageView, JPanel imagePanelContainer2,
ImagePanel imagePanel2) {
imagePanel.setPreservingRatio(true);
imagePanel.setScalingQualitHigh(false);
imagePanelContainer.setLayout(new BorderLayout());
imagePanelContainer.add(imagePanel, BorderLayout.CENTER);
}
@Override
public boolean isAutoManaged() {
return false;
}
@Override
public boolean requestCustomFocus() {
return false;
}
@Override
public void validateSubForm() throws Exception {
}
@Override
public void addMenuContribution(MenuModel menuModel) {
}
@Override
public String toString() {
return "ImageView [data=" + data + "]";
}
}
}