import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Hashtable;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
public class StringOverImage extends JPanel implements ChangeListener
{
BufferedImage image;
Dimension size;
Font font;
String text;
boolean showText;
int x;
int y;
public StringOverImage(BufferedImage image)
{
this.image = image;
size = new Dimension(image.getWidth(), image.getHeight());
font = getFont().deriveFont(18f);
showText = false;
}
public void stateChanged(ChangeEvent e)
{
JSlider slider = (JSlider)e.getSource();
String name = slider.getName();
if(name.equals("x"))
x = slider.getValue();
else if(name.equals("y"))
y = slider.getValue();
repaint();
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Point origin = getImageOrigin();
g2.drawImage(image, origin.x, origin.y, this);
g2.setPaint(Color.red);
float sx = origin.x + x;
float sy = origin.y + y;
if(showText)
{
g2.setFont(font);
g2.drawString(text, sx, sy);
}
else // show text origin
g2.fill(new Ellipse2D.Double(sx-2, sy-2, 4, 4));
}
private Point getImageOrigin()
{
Point p = new Point();
p.x = (getWidth() - size.width)/2;
p.y = (getHeight() - size.height)/2;
return p;
}
public Dimension getPreferredSize()
{
return size;
}
public static void main(String[] args) throws IOException
{
BufferedImage bi = ImageIO.read(new File("images/cougar.jpg"));
StringOverImage test = new StringOverImage(bi);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JScrollPane(test));
f.getContentPane().add(test.getUIPanel(), "South");
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
private void save()
{
int w = image.getWidth();
int h = image.getHeight();
BufferedImage save = new BufferedImage(w, h, image.getType());
Graphics2D g2 = save.createGraphics();
Point p = getImageOrigin();
g2.translate(-p.x, -p.y);
paint(g2);
g2.dispose();
try
{
ImageIO.write(save, "png", new File("stringOverImage.png"));
}
catch(IOException ioe)
{
System.err.println("write error: " + ioe.getMessage());
}
}
private JPanel getUIPanel()
{
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1.0;
gbc.insets = new Insets(2,0,2,0);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
panel.add(getSliders(), gbc);
panel.add(getEditor(), gbc);
return panel;
}
private JPanel getSliders()
{
JSlider xSlider = getSlider(image.getWidth(), "x");
JSlider ySlider = getSlider(image.getHeight(), "y");
// instantiate member variables
x = xSlider.getValue();
y = ySlider.getValue();
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(xSlider, gbc);
panel.add(ySlider, gbc);
return panel;
}
private JSlider getSlider(int max, String s)
{
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, max, max/2);
slider.setName(s);
slider.setPaintLabels(true);
slider.setLabelTable(getLabels(max, s));
slider.addChangeListener(this);
return slider;
}
private Hashtable getLabels(int n, String s)
{
// generic declaration for j2se 1.5+
//Hashtable<Integer,JComponent> ht = new Hashtable<Integer,JComponent>();
Hashtable ht = new Hashtable(); // non-generic for j2se 1.4-
ht.put(new Integer(0), new JLabel("0"));
int w = getFontMetrics(font).stringWidth(s);
ht.put(new Integer((n-w)/2), new JLabel(s));
ht.put(new Integer(n), new JLabel(String.valueOf(n)));
return ht;
}
private JPanel getEditor()
{
final JTextField editor = new JTextField(8);
final JCheckBox show = new JCheckBox("show");
final JButton save = new JButton("save");
show.setActionCommand("show text");
save.setActionCommand("save");
ActionListener l = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String ac = e.getActionCommand();
if(ac.equals("show text"))
{
text = editor.getText();
showText = show.isSelected();
repaint();
}
else if(ac.equals("save"))
save();
}
};
show.addActionListener(l);
save.addActionListener(l);
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(1,1,1,1);
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(editor, gbc);
gbc.weightx = 0.10;
gbc.fill = GridBagConstraints.NONE;
panel.add(show, gbc);
panel.add(save, gbc);
return panel;
}
}