Работа с изображениями стандартными средствами Java
Графические изображения в приложении помогут сделать интерфейс пользователя не только красивым, но и более понятным.
Способ 1. Добавление изображения с помощью JLabel.
Это, вероятно, самый простой способ, но в тоже время не самый гибкий, поскольку в JLabel отсутствуют способы управления положением добавляемого изображения.
Чтобы добавить изображение в JLabel существует метод setIcon(Icon image).
Также это можно сделать во время создания объекта JLabel с помощью конструктора JLabel(String text, Icon icon, int horizontalAlignment).
package javapicture1;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class JavaPicture
{
private static JLabel jLabel;
public static void main(String[] argv)
{
// Создаем новый объект JLabel.
jLabel = new JLabel();
// Выравниваем по горизонтали.
jLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
// Выравниваем по вертикали
jLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);
// Указываем путь к изображению.
jLabel.setIcon(new ImageIcon(("D:\\ashesandsnow.jpg")));
// Текстовая подпись
jLabel.setText("Ваш комментарий.");
// Создаем объект главного окна приложения.
JFrame f = new JFrame("Picture");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(jLabel);
f.setSize(550,350);
f.setLocation(200,200);
f.setVisible(true);
}
}
Преимуществом данного способа, в отличие от следующего, является поддержка анимированных gif изображений.
Способ 2. Добавление изображения с помощью JPanel.
Использование этого способа заключается в создании нового класса (назовем его PicturePanel) в качестве наследника стандартного JPanel. В новом классе реализуется метод setImageFile(File imageFile), который позволяет загрузить изображение из файла и прорисовать его на фоне JPanel.
public void setImageFile(File imageFile)
{
Try
{
if (imageFile == null)
{
originalImage = null;
}
// Читаем файловый поток.
BufferedImage bi = ImageIO.read(imageFile);
originalImage = bi;
}
catch (IOException ex)
{
// В случае ошибки, выводим сообщение.
System.err.println("Не удалось загрузить изображение!");
ex.printStackTrace();
}
// Перерисовываем компонент уже с новым загруженным изображением.
repaint();
}
При изменении размера панели, размеры изображения также меняются, таким образом создается эффект «резинового» изображения, которое «подстраивается» под размеры окна.
// Реакция на изменение размеров панели - изменение размера изображения.
private void formComponentResized(java.awt.event.ComponentEvent evt)
{
int w = this.getWidth();
int h = this.getHeight();
if ((originalImage != null) && (w > 0) && (h > 0))
{
image = originalImage.getScaledInstance(w, h, Image.SCALE_DEFAULT);
this.repaint();
}
}
Ниже приведен полный листинг демо-проекта с комментариями.
package javapicture2;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class JavaPicture
{
private static JLabel jLabel;
public static void main(String[] argv)
{
// Создаем объект класс PicturePanel.
PicturePanel picturePanel = new PicturePanel();
// Загружаем в него изображение.
picturePanel.setImageFile(new File("D:\\ashesandsnow.jpg"));
// Создаем объект главного окна приложения.
JFrame f = new JFrame("Picture");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(picturePanel);
f.setSize(550,350);
f.setLocation(200,200);
f.setVisible(true);
}
}
class PicturePanel extends JPanel
{
// В объекте класса храним 2 изображения: оригинальное и текущее.
// Оригинальное используется для получения текущего в зависимости от размеров
панели.
// Текущее рисуется на панели на панели.
private BufferedImage originalImage = null;
private Image image = null;
public PicturePanel()
{
initComponents();
}
private void initComponents()
{
addComponentListener(new java.awt.event.ComponentAdapter()
{
public void componentResized(java.awt.event.ComponentEvent evt)
{
formComponentResized(evt);
}
});
}
// Реакция на изменение размеров панели - изменение размера изображения.
private void formComponentResized(java.awt.event.ComponentEvent evt)
{
int w = this.getWidth();
int h = this.getHeight();
if ((originalImage != null) && (w > 0) && (h > 0))
{
image = originalImage.getScaledInstance(w, h, Image.SCALE_DEFAULT);
this.repaint();
}
}
@Override
public void paint(Graphics g)
{
super.paint(g);
/ Прорисовка изображения.
if (image != null)
{
g.drawImage(image, 0, 0, null);
}
// Прорисовка компонент.
super.paintChildren(g);
super.paintBorder(g);
}
public BufferedImage getImage()
{
return originalImage;
}
public void setImage(BufferedImage image)
{
this.image = image;
}
public void setImageFile(File imageFile)
{
try
{
if (imageFile == null)
{
originalImage = null;
}
// Читаем файловый поток.
BufferedImage bi = ImageIO.read(imageFile);
originalImage = bi;
}
catch (IOException ex)
{
// В случае ошибки, выводим сообщение.
System.err.println("Не удалось загрузить изображение!");
ex.printStackTrace();
}
// Перерисовываем компонент уже с новым загруженным изображением.
repaint();
}
}
Изменение размеров окна приводит к пропорциональному изменению размеров изображения.
Важным преимуществом приведенного метода является возможность добавлять другие контролы (элементы GUI) на созданный объект PicturePanel, т.е. использовать его в качестве компонента-контейнера, добиваясь тем самым достижения эффекта фонового изображения.
Способ 3. Добавление изображения с помощью класса Image.
Простой способ, который заключается в создании объекта Image, а затем его отрисовку с помощью метода drawImage() объекта типа Graphics в методе paint() объекта типа JFrame.
package javapicture3;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JFrame;
public class JavaPicture extends JFrame
{
public static void main(String[] args)
{
JavaPicture f = new JavaPicture();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(460,370);
f.setLocation(200,100);
f.setVisible(true);
}
@Override
public void paint(Graphics gr)
{
super.paint(gr);
Image img = getToolkit().getImage("D:\\ashesandsnow.png");
gr.drawImage(img,30,50,this);
}
}
Данный метод хорош тем, что объекты Image можно обрабатывать с помощью фильтров:
• CropImageFilter (int x, int у, int w, int h) — выделяет фрагмент изображения, указанный в приведенном конструкторе;
• RGBimageFilter — позволяет изменять отдельные пикселы; это абстрактный класс, он требует расширения и переопределения своего метода filterRGBO;
• RepдicateScaieFilter (int w, int h) — изменяет размеры изображения на указанные в приведенном конструкторе, дублируя строки и/или столбцы при увеличении размеров или убирая некоторые из них при уменьшении;
• AreaAveragingScaleFilter (int w, int h) — расширение предыдущего класса; использует более сложный алгоритм изменения размеров изображения
Применяются классы-фильтры совместно с классом-поставщиком, реализующим интерфейс ImageProducer — классом FilteredlmageSource. Этот класс преобразует уже готовую продукцию, полученную от другого поставщика producer, используя для преобразования объект filter класса-фильтра imageFilter или его подкласса.