Java, Text on Image, update - java

I want to write some text on a image(BufferedImage), but when the text is updated the new text is written over the old one, e.g. all numbers are written in same place, Can someone help.
i'm usins this code:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Prove extends JPanel {
int size = 800;
private BufferedImage sc ;
JLabel label ;
private int counter =0 ;
public Prove()
{
JFrame frame = new JFrame();
frame.getContentPane().add(this);
frame.setSize(2*size, size);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
try{ sc = ImageIO.read(new File("Images/ser.jpg"));
label =new JLabel(new ImageIcon(sc));
this.add(label);
}catch(IOException e){}
}
public void paintComponent(Graphics g)
{
g.setColor(Color.GRAY);
g.fillRect(0,0, getWidth(),getHeight()); //prapavijen
Graphics2D g2 = (Graphics2D)g;
paintScore(g2);
}
public void paintScore(Graphics g2)
{
if(sc != null)
{
Graphics gi = sc.createGraphics();
gi.setFont(new Font("Times New Roman", Font.BOLD, 20));
String r = counter+"";
gi.drawString(r, 20, 20);
counter ++;
this.repaint();
try{Thread.sleep(500);}
catch(InterruptedException e){}
System.out.println(counter);
}
}
public static void main(String[] args)
{
new Prove();
}
}

There is no reason to draw the text directly on the image. Simply draw the image to the component Graphics instance then draw the string to the same Graphics.

You are drawing the text to the same position, it is bound to overwrite
gi.drawString(r, 20, 20);
You will need to change the vertical coordinate if you want the new text to appear below the old one

You must keep an unmodified copy of the original image. Try this pseudocode:
BufferedImage img1 = loadImage();
And in your paint code:
BufferedImage img2 = createEmptyImage( img1 ); // same size, mode and depth
Graphics g = img2.getGraphics();
try {
g.draw( img1 ); // background
g.drawString(); // render text on top of it
} finally {
g.dispose();
}

Related

How to put user defined text on image?

I would like to get user defined text on image, like if I'll make two text fields, one is for name and second for date so when I input someone's name and date, after inputting if I clicked OK then it'll display in that image.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class billFrame extends JFrame
{
public billFrame()
{
JFrame f1 = new JFrame("Billng Application");
f1.setDefaultCloseOperation(EXIT_ON_CLOSE);
f1.setSize(500,500);
f1.setBounds(30, 50, 500, 700);
f1.setExtendedState(JFrame.MAXIMIZED_BOTH);
ImageIcon icon = new
ImageIcon("C:\\Users\\Dhaval\\Downloads\\shrihari.png");
Image image = icon.getImage();
JPanel panel1;
panel1 = new JPanel()
{
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 1400, 0, 500, 700, this);
}
#Override
public Dimension getPreferredSize()
{
return new Dimension(320, 200);
}
};
f1.add(panel1);
panel1.setVisible(true);
panel1.setLayout(null);
JLabel name = new JLabel("Name :");
name.setVisible(true);
name.setLocation(100,100);
name.setSize(100,100);
panel1.add(name);
JTextField namet = new JTextField();
namet.setVisible(true);
namet.setLocation(150, 137);
namet.setSize(200,30);
panel1.add(namet);
f1.setVisible(true);
}
#SuppressWarnings("unchecked")
public static void main(String args[])
{
billFrame bf = new billFrame();
}
}
Here is sample:
static void addTextWatermark(String text, File sourceImageFile, File destImageFile) {
try {
BufferedImage sourceImage = ImageIO.read(sourceImageFile);
Graphics2D g2d = (Graphics2D) sourceImage.getGraphics();
// initializes necessary graphic properties
AlphaComposite alphaChannel = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f);
g2d.setComposite(alphaChannel);
g2d.setColor(Color.BLUE);
g2d.setFont(new Font("Arial", Font.BOLD, 64));
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle2D rect = fontMetrics.getStringBounds(text, g2d);
// calculates the coordinate where the String is painted
int centerX = (sourceImage.getWidth() - (int) rect.getWidth()) / 2;
int centerY = sourceImage.getHeight() / 2;
// paints the textual watermark
g2d.drawString(text, centerX, centerY);
ImageIO.write(sourceImage, "png", destImageFile);
g2d.dispose();
System.out.println("The tex watermark is added to the image.");
} catch (IOException ex) {
System.err.println(ex);
}
}
And here is usage
File sourceImageFile = new File("name.png");
File destImageFile = new File("anothername.png");
addTextWatermark("Text", sourceImageFile, destImageFile);
Or you can us libs for that. For example: http://www.gif4j.com

Change setBackground(Color.Red) to an Image [duplicate]

I draw an image which is my background image, everything is fine but when I'm trying to add some JButtons to the frame the whole business goes wrong the picture that I drew disappear and I see the original background.
The picture drawing looks like that:
public void paint(Graphics g){
g.drawImage(bg, 0, 0, null);
}
I guess my problem is something with the paint method, need to be mentioned that I'm extending the JFrame class.
edit:
Here are some pictures to demonstrate what I mean.
It first draw my image:
And when I move my mouse to the place that my buttons should have been drew, that's what I get:
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.net.URL;
import javax.imageio.ImageIO;
public class FrameWithBG {
public static void main(String[] args) throws Exception {
URL url = new URL("http://i.stack.imgur.com/OVOg3.jpg");
final BufferedImage bg = ImageIO.read(url);
Runnable r = new Runnable() {
#Override
public void run() {
JPanel c = new PanelWithBackgroundImage(bg);
c.setLayout(new GridLayout(0,5,16,16));
c.setBorder(new EmptyBorder(10, 10, 10, 10));
for (int ii = 1; ii < 26; ii++) {
c.add(new JButton("Button " + ii));
}
JFrame f = new JFrame(c.getClass().getSimpleName());
f.add(c);
f.pack();
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
class PanelWithBackgroundImage extends JPanel {
Image bg;
PanelWithBackgroundImage(Image bg) {
this.bg = bg;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bg, 0, 0, getWidth(), getHeight(), this);
}
}

Swing Java Rotate JLabel but text be erased

I'm using swing Java to try to do something with java. Now I want to rotate JLabel and I did that. But unfortunelately, a part of my text in JLabel is erased (as in the image below). I have tried search but seem no one has problems as same as mine. I guess it's occured caused JLabels they overlaped.
and this is my code
serviceName[j] = new JLabel(name){
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
aT.rotate(Math.toRadians(300));
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g);
}
};
Can you give me the way to solved it
You should restore original transform and clip after your painting. Like this
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
g2.rotate(Math.toRadians(300));
super.paintComponent(g);
g2.setTransform(aT);
g2.setClip(oldshape);
}
Your JLabel subclass should also override getPreferredSize() to report the size it will be when it is rotated; otherwise the any layout manager that uses asks your component for its preferred size will use JLabel's version, which assumes the text is drawn horizontally.
Instead of attempting to rotate the component, another approach would be to create a Text Icon and add the Icon to a JLabel.
Once you have created the TextIcon you can then create a Rotated Icon to add to the label. The RotatedIcon will calculate the proper size of the Icon so therefore the size of the label will also be correct and no custom painting is required.
So the basic code would be something like:
JLabel label = new JLabel();
TextIcon textlIcon = new TextIcon(label, "Rotated Text");
label.setIcon( new RotatedIcon(textIcon, 300) );
Edit:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.border.*;
import javax.swing.table.*;
import java.io.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
OverlapLayout layout = new OverlapLayout(new Point(20, 0));
setLayout( layout );
addLabel("one");
addLabel("two");
addLabel("three or more");
addLabel("four");
}
private void addLabel(String text)
{
JLabel label = new JLabel();
TextIcon textIcon = new TextIcon(label, text);
label.setIcon( new RotatedIcon(textIcon, 300) );
label.setVerticalAlignment(JLabel.BOTTOM);
add(label);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
This example also uses the Overlap Layout so the labels can be painted over top of one another.
You may find some hints from this small program. Experiment on the values of setPrefferedSize to have more ideas. If you still can't solve the problem, please edit and add more codes in your question above.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import javax.swing.*;
public class InclinedLabels extends JFrame{
/** Creates a new instance of InclinedLabels */
public InclinedLabels() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JPanel jPanel1 = new JPanel();
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
add(jPanel1);
JPanel jPanel2 = new JPanel();
jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel2.setPreferredSize(new Dimension(10, 100));
add(jPanel2, BorderLayout.NORTH);
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel1.setPreferredSize(new java.awt.Dimension(200, 200));
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-400)/2, (screenSize.height-352)/2, 300, 352);
String str = "The quick brown fox jumps over the lazy dog";
String[] word = str.split(" ");
JLabel[] serviceName = new JLabel[str.length()];
String name;
for (int j=0; j<word.length; j++) {
name = word[j];
serviceName[j] = new JLabel(name){
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
aT.rotate(Math.toRadians(300));
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g);
}
};
serviceName[j].setPreferredSize(new Dimension(50,20));
serviceName[j].setBorder(BorderFactory.createLineBorder(Color.RED));
jPanel1.add(serviceName[j]);
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new InclinedLabels().setVisible(true);
}
});
}
}
Update:
I found a much closer hint that may solve this problem. The big factor here is the component layout. The null layout allows overlapping of JLabel components so it is the most appropriate layout to be used here. Then you have to customize the location and size of the labels through the setBounds method. In the code below there is serviceName[j].setBounds(xOffset + j*20,180, 170, 15); So in every loop iteration, the x location of the label is increased by 20. The size of all labels is 170 by 15. I also placed temporary borders to the components to help in understanding the output.
import java.awt.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;
public class InclinedLabels extends JFrame{
/** Creates a new instance of InclinedLabels */
public InclinedLabels() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-360)/2, (screenSize.height-352)/2, 360, 352);
JPanel jPanel1 = new JPanel();
jPanel1.setBorder(BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel1.setLayout(null); // null layout allows overlapping of components
add(jPanel1);
JPanel jPanel2 = new JPanel();
jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel2.setPreferredSize(new Dimension(10, 100));
add(jPanel2, BorderLayout.NORTH);
String str = "The quick brown fox jumpsssssssssssss123456 over the lazy dogssssssssssssss123456";
String[] word = str.split(" ");
JLabel[] serviceName = new JLabel[str.length()];
String name;
int xOffset = 30;
for (int j=0; j<word.length; j++) {
name = word[j];
serviceName[j] = new JLabel(name){
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
aT.rotate(Math.toRadians(300));
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g2);
}
};
serviceName[j].setBounds(xOffset + j*20,180, 170, 15); // experiment here
serviceName[j].setBorder(BorderFactory.createLineBorder(Color.RED));
jPanel1.add(serviceName[j]);
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new InclinedLabels().setVisible(true);
}
});
}
}
The limitation that I found in the code above is the width of the parent panel. In the example, the label having the text dogssssssssssssss123456 was not printed in whole. This can be overcome by increasing the width of the frame which in turn increases the width of jPanel1.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
public class Test {
public static void main(String[] args) {
// Create the first label, which will be rotated later.
Test.RotateLabel one = new Test.RotateLabel( "Rotated", 100, 100 );
one.setRotation( 270 );
JLayeredPane pane = new JLayeredPane();
pane.setLayer( one, JLayeredPane.DEFAULT_LAYER );
pane.add( one );
pane.setBorder(new javax.swing.border.LineBorder(Color.BLACK,1));
// Put the container pane in a frame and show the frame.
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( pane );
frame.setSize( 500, 500 );
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
static class RotateLabel extends JLabel {
private static final long serialVersionUID = 1L;
private int angle = 0;
public RotateLabel( String text, int x, int y ) {
super( text );
setBorder( new javax.swing.border.CompoundBorder(
new javax.swing.border.LineBorder( Color.red, 1), getBorder() ) );
int width = getPreferredSize().width;
int height = getPreferredSize().height;
setBounds(x, y, width, height);
}
#Override
public void paintComponent( Graphics g ) {
Graphics2D gx = (Graphics2D) g;
Shape old = gx.getClip();
gx.rotate(-Math.toRadians(45), getWidth() / 2, getHeight() / 2);
gx.setClip(old);
super.paintComponent(gx);
}
public void setRotation( int angle ) { this.angle = angle; }
}

Java window doesn't repaint properly until I resize the window manually

I am using a quite basic setup with a class extending JPanel, which I add to a JFrame.
import java.awt.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
public class PinTestMCVE extends JPanel implements ActionListener{
BufferedImage loadedImage;
JButton calcButton;
public static void main(String[] args) {
new PinTestMCVE();
}
public PinTestMCVE() {
loadedImage = getTestImage();
JPanel toolbarPanel = new JPanel();
calcButton = new JButton("calcButton...");
toolbarPanel.add(calcButton);
calcButton.addActionListener(this);
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.getContentPane().setLayout(new BorderLayout());
jf.getContentPane().add(toolbarPanel, BorderLayout.NORTH);
jf.getContentPane().add(this, BorderLayout.CENTER);
jf.setSize(1250, 950);
jf.setVisible(true);
}
public void paintComponent(Graphics g) {
g.drawImage(loadedImage, 0, 0, this);
}
public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent " + e.getActionCommand());
if(e.getSource().equals(calcButton)){
this.repaint();
}
}
//Please ignore the inner workings of this
public static BufferedImage getTestImage(){
BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setPaint(Color.GRAY);
g2d.fillRect ( 0, 0, image.getWidth(), image.getHeight() );
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.gray);
int x = 5;
int y = 7;
GradientPaint redtowhite = new GradientPaint(x, y, Color.red, 200, y, Color.blue);
g2d.setPaint(redtowhite);
g2d.fill(new RoundRectangle2D.Double(x, y, 200, 200, 10, 10));
return image;
}
}
What happens is that INITIALLY the window is painted properly, but once paintComponent is called, a strip of the old image (with the same height as the toolbar panel) is visible below the newly painted images - similar to playing card sticking out from a deck. But then, if I manually resize the window by for instance dragging the border, the background is grayed out as it should.
What is going on and how do I fix this?
As outlined here, you need to pack() the frame before calling setVisible(). You can override getPreferredSize() to specify a suitable initial Dimension. Also consider using a Border. See also Initial Threads.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.*;
public class PinTestMCVE extends JPanel implements ActionListener{
private static final int SIZE = 200;
BufferedImage loadedImage;
JButton calcButton;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new PinTestMCVE();
}
});
}
public PinTestMCVE() {
loadedImage = getTestImage();
JPanel toolbarPanel = new JPanel();
calcButton = new JButton("calcButton...");
toolbarPanel.add(calcButton);
calcButton.addActionListener(this);
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(toolbarPanel, BorderLayout.NORTH);
jf.add(this, BorderLayout.CENTER);
jf.pack();
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(loadedImage, 0, 0, this);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent " + e.getActionCommand());
if(e.getSource().equals(calcButton)){
this.repaint();
}
}
//Please ignore the inner workings of this
public static BufferedImage getTestImage(){
BufferedImage image = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setPaint(Color.GRAY);
g2d.fillRect ( 0, 0, image.getWidth(), image.getHeight() );
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.gray);
GradientPaint redtowhite = new GradientPaint(5, 5, Color.red, SIZE, 5, Color.blue);
g2d.setPaint(redtowhite);
g2d.fill(new RoundRectangle2D.Double(5, 5, SIZE - 10, SIZE - 10, 10, 10));
return image;
}
}

java ImageObserver stop updating an animated gif

textPane contains text and animated gif images. imageUpdate used to update each new gif frame. When I delete a image from textPane, imageupdate continues to update it. How can I stop it?
How to make imageupdate updated only image that got a new frame rather than the entire textPane? imageupdate always displays the x = 0 and y = 0, although the images are in the other coordinates and I can not get a specific image rectangle.
Image 001.gif http://plasmon.rghost.ru/37834058.image
Image 000.gif http://plasmon.rghost.ru/37834053.image
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.*;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
import javax.swing.*;
import java.awt.BorderLayout;
import javax.swing.text.*;
public class HighlightExample {
public static JTextPane textPane;
public static HTMLEditorKit kit = new HTMLEditorKit();
public static char c = (char)(int)10022007;
public static void main(String[] args) {
final JTextField tf = new JTextField();
JFrame f = new JFrame("Highlight example");
textPane = new JTextPane(){
#Override
public void paintComponent(Graphics g) {
Graphics2D graphics2d = (Graphics2D) g;
graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
try {
Document d = (this).getDocument();
String content = d.getText(0, d.getLength()).toLowerCase();
int lastIndex = 0;
super.paintComponent(g);
Image[] image=new Image[] {Toolkit.getDefaultToolkit().getImage("000.gif"), Toolkit.getDefaultToolkit().getImage("001.gif")};
while ((lastIndex = content.indexOf(c, lastIndex)) != -1) {
g.drawImage(image[Integer.parseInt(content.substring(lastIndex+1, lastIndex+4))],(int)(this).modelToView(lastIndex).getX(),(int)(this).modelToView(lastIndex).getY(),this);
++lastIndex;
}
} catch (BadLocationException e) {}
}
public boolean imageUpdate( Image img, int flags, int x, int y, int w, int h )
{
System.out.println("Image update:" + img + " flags="+flags+" x="+x+" y="+y+" w="+w+" h="+h);
repaint(); //repaint(x, y, w, h);
return true;
}
};
tf.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
textPane.setText(tf.getText().trim());
}
});
textPane.setEditorKit(kit);
StyleSheet styleSheet = kit.getStyleSheet();
styleSheet.addRule("sm {color: red;}");
JPanel pane = new JPanel();
pane.setLayout(new BorderLayout());
pane.add(tf, "Center");
f.getContentPane().add(pane, "South");
f.getContentPane().add(new JScrollPane(textPane), "Center");
textPane.setEditable(false);
textPane.setContentType("text/html");
textPane.setText("ab<span style=\"font-size: 0px;color: white;\">"+c+"001</span> пїЅdefghijkl bпїЅlmnop12345678<span style=\"font-size: 0px;color: white;\">"+c+"000</span> ;)<br><br><br><br><br><br><br><br>");
f.setSize(400, 400);
f.setVisible(true);
}
}
load the images only once not every time you repaint
for each image hold a list where you drew it during the last paint
in imageUpdate use the given img to select the list of coordinates you populated in paintComponent for that very image and only repaint regions for that coordinates
Note: images not currently used in your text will still call imageUpdate but are automatically skipped since their list of coordinates should be empty

Categories