fix IllegalArgumentException
[fedora-idea.git] / platform / lang-impl / src / com / intellij / codeInsight / preview / ImagePreviewComponent.java
blob54f723095065d08a7c4a4dc8e223e44f6c22bfb4
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.intellij.codeInsight.preview;
19 import com.intellij.openapi.util.Key;
20 import com.intellij.openapi.vfs.VirtualFile;
21 import com.intellij.psi.PsiElement;
22 import com.intellij.psi.PsiFileSystemItem;
23 import com.intellij.psi.PsiReference;
24 import com.intellij.reference.SoftReference;
25 import com.intellij.util.ui.UIUtil;
26 import org.jetbrains.annotations.NotNull;
28 import javax.imageio.ImageIO;
29 import javax.imageio.ImageReadParam;
30 import javax.imageio.ImageReader;
31 import javax.imageio.stream.ImageInputStream;
32 import javax.swing.*;
33 import java.awt.*;
34 import java.awt.image.BufferedImage;
35 import java.awt.image.ColorModel;
36 import java.io.ByteArrayInputStream;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import java.util.Arrays;
40 import java.util.Iterator;
41 import java.util.List;
43 /**
44 * @author spleaner
46 public class ImagePreviewComponent extends JPanel {
47 private static final Key<Long> TIMESTAMP_KEY = Key.create("Image.timeStamp");
48 private static final Key<SoftReference<BufferedImage>> BUFFERED_IMAGE_REF_KEY = Key.create("Image.bufferedImage");
49 private static final Key<String> FORMAT_KEY = Key.create("Image.format");
51 private static final List<String> supportedExtensions = Arrays.asList(ImageIO.getReaderFormatNames());
53 private ImagePreviewComponent(@NotNull final BufferedImage image) {
54 setLayout(new BorderLayout());
56 add(new ImageComp(image), BorderLayout.CENTER);
57 add(createLabel(image), BorderLayout.SOUTH);
59 setBackground(UIUtil.getToolTipBackground());
60 setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.black), BorderFactory.createEmptyBorder(5, 5, 5, 5)));
63 @NotNull
64 private static JLabel createLabel(@NotNull final BufferedImage image) {
65 final int width = image.getWidth();
66 final int height = image.getHeight();
67 final ColorModel colorModel = image.getColorModel();
68 final int i = colorModel.getPixelSize();
69 return new JLabel(width + "x" + height + ", " + i + "bpp");
72 @SuppressWarnings({"AutoUnboxing"})
73 private static boolean refresh(@NotNull VirtualFile file) throws IOException {
74 Long loadedTimeStamp = file.getUserData(TIMESTAMP_KEY);
75 SoftReference<BufferedImage> imageRef = file.getUserData(BUFFERED_IMAGE_REF_KEY);
76 if (loadedTimeStamp == null || loadedTimeStamp < file.getTimeStamp() || imageRef == null || imageRef.get() == null) {
77 try {
78 final byte[] content = file.contentsToByteArray();
79 InputStream inputStream = new ByteArrayInputStream(content, 0, content.length);
80 ImageInputStream imageInputStream = ImageIO.createImageInputStream(inputStream);
81 try {
82 Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(imageInputStream);
83 if (imageReaders.hasNext()) {
84 ImageReader imageReader = imageReaders.next();
85 try {
86 file.putUserData(FORMAT_KEY, imageReader.getFormatName());
87 ImageReadParam param = imageReader.getDefaultReadParam();
88 imageReader.setInput(imageInputStream, true, true);
89 int minIndex = imageReader.getMinIndex();
90 BufferedImage image = imageReader.read(minIndex, param);
91 file.putUserData(BUFFERED_IMAGE_REF_KEY, new SoftReference<BufferedImage>(image));
92 return true;
94 finally {
95 imageReader.dispose();
99 finally {
100 imageInputStream.close();
103 finally {
104 // We perform loading no more needed
105 file.putUserData(TIMESTAMP_KEY, System.currentTimeMillis());
108 return false;
111 public static JComponent getPreviewComponent(final PsiElement parent) {
112 final PsiReference[] references = parent.getReferences();
113 for (final PsiReference reference : references) {
114 final PsiElement fileItem = reference.resolve();
115 if (fileItem instanceof PsiFileSystemItem) {
116 final PsiFileSystemItem item = (PsiFileSystemItem) fileItem;
117 if (!item.isDirectory()) {
118 final VirtualFile file = item.getVirtualFile();
119 if (file != null && supportedExtensions.contains(file.getExtension())) {
120 try {
121 refresh(file);
122 SoftReference<BufferedImage> imageRef = file.getUserData(BUFFERED_IMAGE_REF_KEY);
123 if (imageRef != null) {
124 return new ImagePreviewComponent(imageRef.get());
127 catch (IOException e) {
128 // nothing
135 return null;
138 private static class ImageComp extends JComponent {
139 private final BufferedImage myImage;
140 private final Dimension myPreferredSize;
142 private ImageComp(@NotNull final BufferedImage image) {
143 myImage = image;
145 if (image.getWidth() > 300 || image.getHeight() > 300) {
146 // will make image smaller
147 final float factor = 300.0f / Math.max(image.getWidth(), image.getHeight());
148 myPreferredSize = new Dimension((int)(image.getWidth() * factor), (int)(image.getHeight() * factor));
150 else {
151 myPreferredSize = new Dimension(image.getWidth(), image.getHeight());
155 public void paint(final Graphics g) {
156 super.paint(g);
157 Rectangle r = getBounds();
158 final int width = myImage.getWidth();
159 final int height = myImage.getHeight();
161 g.drawImage(myImage, 0, 0, r.width > width ? width : r.width, r.height > height ? height : r.height, this);
164 public Dimension getPreferredSize() {
165 return myPreferredSize;
168 public Dimension getMinimumSize() {
169 return getPreferredSize();
172 public Dimension getMaximumSize() {
173 return getPreferredSize();