javaswingjscrollpanemousemotionlistener

Some part of the image disappears when I scroll up and down on a jscrollpane


Hi guys I have a problem with Images drawn in a JPanel.There is no problem when the images are drawn to the panel. The Problemm occurn when I scroll up or down the image. The part of the image that was not seen in the viewport is painted white when return to that part again.

I added a BufferedImage in a JPanel. I can also resize the image using AffineTransform. The problem is when I added a JScollPane to my image, whenever I scroll up or down the scrollpane some part of the image disappears ..

I also tried using drawRenderedImage it did solve the problem about the scroll but it messed up other functions.

this is the best concise code I can make;

package convert;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;

public class ZoomTest {

    public static void main(String[] args) {
        ImagePanel panel = new ImagePanel();

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        f.getContentPane().add(new JScrollPane(panel));
        f.setSize(1200, 1200);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

class ImagePanel extends JPanel {

    BufferedImage image;
    double scale;

    public ImagePanel() {
        loadImage();
        scale = .38;
        addMouseWheelListener(new MouseWheelListener() {

            @Override
            public void mouseWheelMoved(MouseWheelEvent e) {
                int rotation = e.getWheelRotation();
                if (rotation < 0) {
                    scale -= .05;
                } else {
                    scale += .05;
                }
                if (scale < 0) {
                    scale = 0;
                }

                revalidate();
                repaint();

            }
        });

    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        double x = (getWidth() - scale * image.getWidth()) / 2;
        double y = (getHeight() - scale * image.getHeight()) / 2;

        AffineTransform at = new AffineTransform();
        at.translate(x, y);

        at.scale(scale, scale);
        g2.setTransform(at);

        g2.drawImage(image, 0, 0, null);

    }

    public Dimension getPreferredSize() {
        int w = (int) (scale * image.getWidth());
        int h = (int) (scale * image.getHeight());
        return new Dimension(w, h);
    }

    private void loadImage() {
        String fileName = "c:\\users\\john ebarita\\downloads\\lorem-ipsum-1.jpg";
        try {
            image = ImageIO.read(new File(fileName));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Solution

  • Take a look at Graphics2D#drawImage(Image, AffineTransform, ImageObserver). May be it helps.

    package convert;
    
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.net.*;
    import java.util.ArrayList;
    import javax.imageio.ImageIO;
    import javax.swing.*;
    import javax.swing.event.*;
    
    public class ZoomTest2 {
      public static void main(String[] args) {
        ImagePanel panel = new ImagePanel();
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new JScrollPane(panel));
        f.setSize(1200, 1200);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
      }
    }
    
    class ImagePanel extends JPanel {
      BufferedImage image;
      double scale;
    
      public ImagePanel() {
        loadImage();
        scale = .38;
        addMouseWheelListener(new MouseWheelListener() {
          @Override
          public void mouseWheelMoved(MouseWheelEvent e) {
            int rotation = e.getWheelRotation();
            if (rotation < 0) {
              scale -= .05;
            } else {
              scale += .05;
            }
            if (scale < 0) {
              scale = 0;
            }
            revalidate();
            repaint();
          }
        });
      }
    
      @Override
      protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();
    
        double x = (getWidth() - scale * image.getWidth()) / 2;
        double y = (getHeight() - scale * image.getHeight()) / 2;
        AffineTransform at = new AffineTransform();
        at.translate(x, y);
        at.scale(scale, scale);
    
        // g2.setTransform(at);
        // g2.drawImage(image, 0, 0, this);
        g2.drawImage(image, at, this);
    
        // or:
        // AffineTransform atf = g2.getTransform();
        // atf.concatenate(at);
        // g2.setTransform(atf);
        // g2.drawImage(image, 0, 0, this);
    
        g2.dispose();
      }
    
      public Dimension getPreferredSize() {
        int w = (int)(scale * image.getWidth());
        int h = (int)(scale * image.getHeight());
        return new Dimension(w, h);
      }
    
      private void loadImage() {
        String fileName = "aaa.png";
        try {
          image = ImageIO.read(new File(fileName));
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }