more..
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class ImagePanel extends JPanel {
// 어느위치에어떤글자를찍을지를저장할정보클래스
static class MessageWithPoint {
private String message;
private Point p;
MessageWithPoint(String message, Point p) {
this.message = message;
this.p = p;
}
String getMessage() {
return message;
}
Point getPoint() {
return p;
}
}
private Image img;
// 여러개를찍어야하니깐정보클래스가여러개들어갈수있도록List로관리
private List<MessageWithPoint> messages;
// 초기화
public ImagePanel() {
// 메세지를보여줄리스트객체생성
messages = new ArrayList<MessageWithPoint>();
// 마우스클릭하면메세지와글자가찍힌포인트를저장하게마우스리스너등록
// 귀찮으니깐익명클래스로만들어주자
addMouseListener(new MouseListener() {
// 우리가관심이있는것은클릭이다 클릭만처리하자
// MouseAdapter로처리할수도있으나 초보는Listener계열을사용하여
// 어떤동작을통지받을수있는지알아놓는게좋다
// 실은나도Listener부터구현하고나중에다시Adapter로변경한다
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
public void mouseClicked(MouseEvent e) {
// 클릭된위치
Point p = e.getPoint();
// 저장할글자
String message = "Point : " + p.x + ", " + p.y ;
// 메세지추가
addMessageWithPoint(message, p);
}
});
}
// 글자를추가할수있게한다
// 외부에서MessageWithPoint객체를만들면외부코드가지저분해지니깐
// 각정보를따로받아서내부에서MessageWithPoint 객체를만들어주자
private void addMessageWithPoint(String message, Point p) {
// 글자를추가하고있는동안에그려서는안된다
MessageWithPoint mwp = new MessageWithPoint(message,p);
synchronized(messages) {
messages.add(mwp);
}
// 메세지가추가되었으니새롭게그려보아야하지않겠나
repaint();
}
public final void setImage(Image img) {
this.img = img;
repaint();
}
public final void setImage(File f) throws IOException {
if(f == null) {
throw new IOException("param is null.");
}
if(!f.exists()) {
throw new IOException("file is not exists.");
}
BufferedImage image = ImageIO.read(f);
setImage(image);
}
public final Image getImage() {
return img;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// draw image
Image image = getImage();
if(image != null) {
g.drawImage(image, 0, 0, this);
// store old font / fore color
Font oldFont = g.getFont();
Color oldForeColor = g.getColor();
// 글자들을가지고와서그리는동안 다른글자가추가되어서는안된다
// for 루프를도는동안추가된것은어느위치에추가되었는지알수없기때문에문제가된다
// ( 실제로iterable객체를for루프를도는동안에 추가 삭제되면예외가발생하게되어있다 )
Font drawFont = new Font("Dialog", Font.BOLD, 20);
g.setColor(Color.RED);
g.setFont(drawFont);
synchronized(messages) {
for ( MessageWithPoint eachMessageWithPoint : messages ) {
String message = eachMessageWithPoint.getMessage();
Point p = eachMessageWithPoint.getPoint();
g.drawString(message, p.x, p.y);
}
}
// reset old font / fore color
g.setFont(oldFont);
g.setColor(oldForeColor);
}
}
// for pack method of Window class.
@Override
public Dimension getPreferredSize() {
Image image = getImage();
if(image != null) {
int width = image.getWidth(null);
int height = image.getHeight(null);
return new Dimension(width, height);
} else {
return super.getPreferredSize();
}
}
public static void main(String[] args) throws IOException {
JFrame jframe = new JFrame("ImagePanel Test");
ImagePanel imagePanel = new ImagePanel();
imagePanel.setImage(new File("C:\\dragonfly.jpg"));
jframe.getContentPane().setLayout(new BorderLayout());
jframe.getContentPane().add(imagePanel, BorderLayout.CENTER);
jframe.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jframe.pack();
jframe.setVisible(true);
}
}
댓글 없음:
댓글 쓰기