🔒 Locked
[java] ImageIcon displaying problem
Advertisement
Original Post
Hi, In my application I load a 4275*2672 JPEG file using ImageIcon and displaying it using a self defined JLabel (with scrollbars) on a JFrame. When i display the picture there is no problem at first, but after a repaint (i scroll down, resize the window, etc.) the image blurs. I know for sure it is not because of the large picture, because i had the same problem with smaller pictures (and i had no problem with larger pictures). There is no problem viewing it if i navigate to the file with explorer. So the image is fine to. Maybe i should use a different image class, like bufferedImage, or manual paint using Graphics2d.paintImage. I would also like to be able to zoom in / out eventually although that is not my biggest concern. Any thoughts on this? Thank you.
I am using basic swing, no special stuff.
I create a new class called ScrollablePicture wich extends JLabel and implements Scrollable and MouseMotionListener.
I create an new ImageIcon and set it as Icon on the ScrollablePicture JLabel.
Then i add an JScrollPane containing the ScrollablePicture to a JFrame
On an other forum they told me to clear the buffer, but if i do this, it takes about 1 second to reload the image every time the user scrolls the image.
I create a new class called ScrollablePicture wich extends JLabel and implements Scrollable and MouseMotionListener.
I create an new ImageIcon and set it as Icon on the ScrollablePicture JLabel.
Then i add an JScrollPane containing the ScrollablePicture to a JFrame
On an other forum they told me to clear the buffer, but if i do this, it takes about 1 second to reload the image every time the user scrolls the image.
Hi,
I would suggest that you use the Graphics2D.drawImage() function along with clipping the image and handling the scrolling yourself. As well as setting up a bufferStrategy which will help make for smooth scrolling.
What I mean by clipping is that you only draw the portion of the image that is currently visible by the user and the rest is hidden by the scrollbars.
But try what Giuoco suggested first if you use a BufferStrategy then your problem might be solved. For any further advice I'd have to fiddle around with an example of the problem.
Hope this helps.
I would suggest that you use the Graphics2D.drawImage() function along with clipping the image and handling the scrolling yourself. As well as setting up a bufferStrategy which will help make for smooth scrolling.
What I mean by clipping is that you only draw the portion of the image that is currently visible by the user and the rest is hidden by the scrollbars.
But try what Giuoco suggested first if you use a BufferStrategy then your problem might be solved. For any further advice I'd have to fiddle around with an example of the problem.
Hope this helps.
I would recommend against handling the scrolling yourself. Also the way you are doing it is also not the best. I have done this several times and it works when you do it with a JPanel and a JScrollPane. Also, use image instead of ImageIcon, if you can.
public class App extends JFrame { public App() { Image image; //load image ImagePanel imagePanel = new ImagePanel(image); JScrollPane scroll = new JScrollPane(imagePanel); getContentPane.add(scroll); } public static void main(String args[]) { //start up the App and display it }}class ImagePanel extends JPanel { Image image; Dimension size; public ImagePanel(Image image) { this.image = image; size = new Dimension(image.getWidth(), image.getHeight()); } public void paint(Graphics g) { g.drawImage(image, 0, 0, this); } public Dimension getPreferredSize() { return size; }}
Ah that is a fine solution!
I actually tried something like this before, using an inner JPanel class, overriding the paint method, but it didnt work..
But this example works the same as my method, but now it wont blur anymore (at least i suspect, i cannot say for sure just yet)
I added some extra code so that the speed at which scrollbars traverse increases, and i also added some code that enables the user to drag to the side of the panel thus changing the view.
I create a new ImageIcon class and with the method getImage() i pass it on to the new ImagePanel class. Ill give the complete code, it could come in very usefull:
Thanks!
I actually tried something like this before, using an inner JPanel class, overriding the paint method, but it didnt work..
But this example works the same as my method, but now it wont blur anymore (at least i suspect, i cannot say for sure just yet)
I added some extra code so that the speed at which scrollbars traverse increases, and i also added some code that enables the user to drag to the side of the panel thus changing the view.
I create a new ImageIcon class and with the method getImage() i pass it on to the new ImagePanel class. Ill give the complete code, it could come in very usefull:
package nl.base.apps.requestLog;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Image;import java.awt.Rectangle;import java.awt.event.MouseEvent;import java.awt.event.MouseMotionListener;import java.awt.image.ImageObserver;import javax.swing.JPanel;import javax.swing.Scrollable;import javax.swing.SwingConstants;class ImagePanel extends JPanel implements Scrollable, MouseMotionListener { Image image; Dimension size; private int maxUnitIncrement = 1; public ImagePanel(Image image, ImageObserver observer, int m) { this.image = image; size = new Dimension(image.getWidth(observer), image .getHeight(observer)); maxUnitIncrement = m; // Let the user scroll by dragging to outside the window. setAutoscrolls(true); // enable synthetic drag events addMouseMotionListener(this); // handle mouse drags } public void paint(Graphics g) { g.drawImage(image, 0, 0, this); } public Dimension getPreferredSize() { return size; } public void mouseMoved(MouseEvent e) { } public void mouseDragged(MouseEvent e) { // The user is dragging us, so scroll! Rectangle r = new Rectangle(e.getX(), e.getY(), 50, 50); scrollRectToVisible(r); } public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { // Get the current position. int currentPosition = 0; if (orientation == SwingConstants.HORIZONTAL) { currentPosition = visibleRect.x; } else { currentPosition = visibleRect.y; } // Return the number of pixels between currentPosition // and the nearest tick mark in the indicated direction. if (direction < 0) { int newPosition = currentPosition - (currentPosition / maxUnitIncrement) * maxUnitIncrement; return (newPosition == 0) ? maxUnitIncrement : wPosition; } return ((currentPosition / maxUnitIncrement) + 1) * maxUnitIncrement - currentPosition; } public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { if (orientation == SwingConstants.HORIZONTAL) { return visibleRect.width - maxUnitIncrement; } return visibleRect.height - maxUnitIncrement; } public boolean getScrollableTracksViewportWidth() { return false; } public boolean getScrollableTracksViewportHeight() { return false; } public void setMaxUnitIncrement(int pixels) { maxUnitIncrement = pixels; }}Thanks!
One more thing. All visual components implement ImageObserver, so you don't need to pass in an observer, you can just use the this keyword.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement