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
;
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
;
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)));
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) {
78 final byte[] content
= file
.contentsToByteArray();
79 InputStream inputStream
= new ByteArrayInputStream(content
, 0, content
.length
);
80 ImageInputStream imageInputStream
= ImageIO
.createImageInputStream(inputStream
);
82 Iterator
<ImageReader
> imageReaders
= ImageIO
.getImageReaders(imageInputStream
);
83 if (imageReaders
.hasNext()) {
84 ImageReader imageReader
= imageReaders
.next();
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
));
95 imageReader
.dispose();
100 imageInputStream
.close();
104 // We perform loading no more needed
105 file
.putUserData(TIMESTAMP_KEY
, System
.currentTimeMillis());
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())) {
122 SoftReference
<BufferedImage
> imageRef
= file
.getUserData(BUFFERED_IMAGE_REF_KEY
);
123 if (imageRef
!= null) {
124 return new ImagePreviewComponent(imageRef
.get());
127 catch (IOException e
) {
138 private static class ImageComp
extends JComponent
{
139 private final BufferedImage myImage
;
140 private final Dimension myPreferredSize
;
142 private ImageComp(@NotNull final BufferedImage 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
));
151 myPreferredSize
= new Dimension(image
.getWidth(), image
.getHeight());
155 public void paint(final Graphics 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();