Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 7 of 7

Thread: JScrollPane and programatic scrolling

  1. #1
    Junior Member
    Join Date
    Jan 2013
    Posts
    13
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default JScrollPane and programatic scrolling

    Hello everyone!
    I was trying get answer on other forum but without any reaction so I decided to try here .

    I'm new in JAVA and I'm migrating from C#. I make a simple picture viewer with possibility of zooming using JPanel and JScrollPane. I made a zoom component (buttons + slider) and with events, program is zooming in and out picture which is loaded in JPanel (in code called picViewer1). Everything works, but everytime when I make zoom operation it scrolls to position 0,0. I tried few options and it will be visible in presented code.

    Below I present You a my class which is Swing component iherited from JScrollPane. My idea is to run function
    setScrollPosition(int hPercentage, int vPercentage)

    to scroll to the center of zoomed area after zoom in/out request.
    Full zoom algorithm is in function

    public void setZoom(float zoom)

    Can anybody show me how can I achieve scrolling in program? I'm out of ideas...

    I'm adding my NetBeansProject with source. Please put file pic.jpg in C:/a/pic.jpg:
    javaTest_2013_01_02.zip - Speedy Share - upload your files here

    My today's fight conclusions:

    I turned off function this.picViewer1.refreshImage() [which is resizing picture and JPanel] and removed this.revalidate() and repaint() everywhere [of course I will add it back later].

    hbar.setValue(scrollPosH);
    vbar.setValue(scrollPosV);

    image scrolls to desired location. So my question is what is happening in function refreshImage that scroll is always reseting to zero position?

    PS. It seems that after clicking zoom in image is scrolling but right after is reset to zero position. I know because it is flickering on screen...

    Please help.

    I'm using this solution to scroll picture using KeyListener and it works. Only during resizing it doeasn't work...

    public class ScrolledPicViewer extends javax.swing.JScrollPane
    {
        /**
         * Creates new form ScrolledPicViewer
         */
        public ScrolledPicViewer()
        {
            super();
     
            initComponents();
     
            this.horizontalScrollBarPolicy = HORIZONTAL_SCROLLBAR_ALWAYS;
            this.verticalScrollBarPolicy = VERTICAL_SCROLLBAR_ALWAYS;
     
            this.getViewport().add(this.picViewer1, BorderLayout.CENTER);
        }
     
        public final void setScaleImage(boolean scaleImage)
        {
            this.picViewer1.setScaleImage(scaleImage);
        }
     
        public final boolean getScaleImage()
        {
            return this.picViewer1.getScaleImage();
        }
     
        /*
         * Gets horizontal scroll position in percentage
         */
        public final int getHorizontalScrollPosition()
        {
            int picWidth = this.picViewer1.getWidth();
            int scrollPos = this.getHorizontalScrollBar().getValue();
     
            int percentage = 0;
     
            if(picWidth > 0)
            {
                percentage = (int)(((float)scrollPos / (float)picWidth)*100);
            }
     
            return percentage;
        }
     
        /*
         * Gets vertical scroll position in percentage
         */
        public final int getVerticalScrollPosition()
        {
            int picHeight = this.picViewer1.getHeight();
            int scrollPos = this.getVerticalScrollBar().getValue();
     
            int percentage = 0;
     
            if(picHeight > 0)
            {
                percentage = (int)(((float)scrollPos / (float)picHeight)*100);
            }
     
            return percentage;
        }
     
        public final void setScrollPosition(int hPercentage, int vPercentage)
        {
            float convFactorH = 0;
            float convFactorV = 0;
     
            int scrollPosH = 0;
            int scrollPosV = 0;
     
            JScrollBar vbar = this.getVerticalScrollBar();
            int maxPositionV = vbar.getMaximum () - vbar.getVisibleAmount();
     
            JScrollBar hbar = this.getHorizontalScrollBar();
            int maxPositionH = hbar.getMaximum () - hbar.getVisibleAmount();
     
            if(hPercentage >= 0 && hPercentage <= 100 && vPercentage >= 0 && vPercentage <= 100)
            {
                convFactorH = (float)hPercentage/100;
                convFactorV = (float)vPercentage/100;
     
                scrollPosH = (int)(convFactorH * maxPositionH);
                scrollPosV = (int)(convFactorV * maxPositionV);
            }
     
            //hbar.setValue(scrollPosH);
            //vbar.setValue(scrollPosV);
     
            this.getViewport().setViewPosition(new Point(-200, -200));
     
            this.repaint();
            this.revalidate();
        }
     
     
        public void setZoom(float zoom)
        {
            int horizontalScrollPosition = this.getHorizontalScrollPosition();
            int verticalScrollPosition = this.getVerticalScrollPosition();
     
            this.picViewer1.setZoom(zoom);
            this.picViewer1.refreshImage();
     
            this.setScrollPosition(horizontalScrollPosition, verticalScrollPosition);
        }
     
        public float getZoom()
        {
            return this.picViewer1.getZoom();
        }
     
        public float getZoomMax()
        {
            return this.picViewer1.getZoomMax();
        }
     
        public float getZoomMin()
        {
            return this.picViewer1.getZoomMin();
        }
     
        public void zoomIn()
        {
            this.picViewer1.zoomIn(0.1F);
            this.picViewer1.refreshImage();
        }
     
        public void zoomOut()
        {
            this.picViewer1.zoomOut(0.1F);
            this.picViewer1.refreshImage();
        }
     
        public void resetZoom()
        {
            this.picViewer1.setZoom(1);
            this.picViewer1.refreshImage();
        }
     
        public void resize()
        {
            this.picViewer1.refreshImage();
        }
     
        public void OpenFromFile(String fileName) throws IOException
        {
            this.picViewer1.OpenFromFile(fileName);
     
            this.refreshImage();
        }
     
        public void refreshImage()
        {
            this.picViewer1.refreshImage();
     
            this.revalidate(); 
            this.validate();
        }
     
        /**
         * This method is called from within the constructor to initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is always
         * regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">                         
        private void initComponents() {
     
            picViewer1 = new javatest.PicViewer();
     
            addComponentListener(new java.awt.event.ComponentAdapter() {
                public void componentResized(java.awt.event.ComponentEvent evt) {
                    formComponentResized(evt);
                }
            });
     
            javax.swing.GroupLayout picViewer1Layout = new javax.swing.GroupLayout(picViewer1);
            picViewer1.setLayout(picViewer1Layout);
            picViewer1Layout.setHorizontalGroup(
                picViewer1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 100, Short.MAX_VALUE)
            );
            picViewer1Layout.setVerticalGroup(
                picViewer1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 100, Short.MAX_VALUE)
            );
     
            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getViewport());
            getViewport().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(picViewer1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(0, 494, Short.MAX_VALUE))
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(picViewer1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(0, 408, Short.MAX_VALUE))
            );
        }// </editor-fold>                       
     
        private void formComponentResized(java.awt.event.ComponentEvent evt) {                                     
            // TODO add your handling code here:
     
            this.picViewer1.refreshImage();
     
            //this.validate();
            //this.repaint();
        }                                    
     
        // Variables declaration - do not modify                    
        private javatest.PicViewer picViewer1;
        // End of variables declaration                  
    }


  2. #2
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,147
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: JScrollPane and programatic scrolling

    The posted code does not compile without errors: missing import statements and classes.
    If you don't understand my answer, don't ignore it, ask a question.

  3. #3
    Junior Member
    Join Date
    Jan 2013
    Posts
    13
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: JScrollPane and programatic scrolling

    Hello Norm!
    Thanks for the answer. I tried to run project on another computer and get error with missing PDFRenderer-0.9.1.jar library. Library is avaiable in folder dist/lib/PDFRenderer-0.9.1.jar, so if you could resolve the problem with showing to NetBeans this library. Everything should work fine. In my case it was like that.

    I want to use this library in my project in the future, so that's why it is there. You can remove all references to this library in file NewJFrame.java and line

    PDFFile curFile;

    It will work too.

    New link:

    http://www.speedyshare.com/xakzF/jav...2013-01-03.zip

    If there will be any missing references problems to library PDFRenderer... please ignore it. It should work anyway .

    Sorry for trouble. I didn't have possibility to check it on other computer. I see pictures on buttons are missing too, but this is not the case. I have to learn how to add resources to project .
    Last edited by brajan1984; January 3rd, 2013 at 04:01 PM. Reason: Adding new link

  4. #4
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,147
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: JScrollPane and programatic scrolling

    Sorry, I'd rather not work with a bunch of non Java SE classes. Also I don't like to download from 3rd party sites. I don't use Netbeans.
    Can you make a small, complete program that compiles, executes and shows the problem and post all of the code here?
    If you don't understand my answer, don't ignore it, ask a question.

  5. #5
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,318
    Thanks
    181
    Thanked 833 Times in 772 Posts
    Blog Entries
    5

    Default Re: JScrollPane and programatic scrolling

    I was trying get answer on other forum but without any reaction so I decided to try here
    It is in everyone's best interest to provide links to said posts. See the link below for reasons why

    This thread has been cross posted here:

    http://www.java-forums.org/awt-swing/67213-jscrollpane-programatic-scrolling.html

    Although cross posting is allowed, for everyone's benefit, please read:

    Java Programming Forums Cross Posting Rules

    The Problems With Cross Posting


  6. #6
    Junior Member
    Join Date
    Jan 2013
    Posts
    13
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: JScrollPane and programatic scrolling

    Ok. First of all sorry for break but I was defeated by flu. Now I see the world so I can continue. I won't be adding add any files now but I will try to describe my problem the best I can with code and pictures.

    My problem is that I don't know where to find cause of this behavior so thanks for patience.

    1. How it was built: On JPanel (PicViewer called picViewer1) I show the picture. picViewer1 is located inside JScrollPane (ScrolledPicViewer).

    2. What I want: I want to zoom picture and scroll (using JScrollPane) to area which is most inresting for me. To simplify the problem I set program to scroll always to 50% of the picture (so the middle) after zoom.

    3. What effect I get:

    First picture is an application after start. Ugly I know but these first versions.

    story1.jpg

    On second picture below You can see that zoom is changed and scroll bars are set in the middle, so on picture should be visible green field, but is black. Picture is reseting to position 0,0. I can only say that functions used to scroll work, becuse I can scroll with keyboard using them (with KeyListener).
    Summarizing everything works until PicViewer (JPanel) is not changing its size.

    story2.jpg

    4. The code: [I deleted some parts of code to make it more readable and focus on the problem. If You miss something please tell me.]

    a. Main zoom function
    @Override
        public void handleZoomChangedEvent(EventObject e) 
        {
            //Get swing component responsible for zoom ui (this one with buttons and slider on red background)
            ZoomHandlerComponent zoomObj = (ZoomHandlerComponent)(e.getSource());
     
            //Gets requested zoom in percentage
            int zoomPrec = zoomObj.getZoom();
     
            //Calculate it to zoom factor
            float zoomFloat = (float)((float)zoomPrec / (float)100);
     
            //Sets requested zoom. 'this.pic' is a ScrolledPicViewer
            this.pic.setZoom(zoomFloat);
     
            //Refresh
            this.pic.refreshVisual();
        }

    b. ScrolledPicViewer

    public class ScrolledPicViewer extends javax.swing.JScrollPane
    {
        /**
         * Creates new form ScrolledPicViewer
         */
        public ScrolledPicViewer()
        {
            super();
     
            initComponents();
     
            this.horizontalScrollBarPolicy = HORIZONTAL_SCROLLBAR_ALWAYS;
            this.verticalScrollBarPolicy = VERTICAL_SCROLLBAR_ALWAYS;
     
            this.getViewport().add(this.picViewer1, null);
        }
     
        /*
         * Gets horizontal scroll position in percentage
         */
        public final int getHorizontalScrollPosition()
        {
            int maxPositionH = this.getHorizontalScrollBar().getMaximum () - this.getHorizontalScrollBar().getVisibleAmount();
            int scrollPos = this.getHorizontalScrollBar().getValue();
     
            int percentage = 0;
     
            if(maxPositionH > 0)
            {
                percentage = (int)(((float)scrollPos / (float)maxPositionH)*100);
            }
     
            return percentage;
        }
     
        public final void setHorizontalScrollPosition(int posPercentage)
        {
            int maxPositionH = this.getHorizontalScrollBar().getMaximum () - this.getHorizontalScrollBar().getVisibleAmount();
            int scrollPos = this.getHorizontalScrollBar().getValue();
     
     
            if(maxPositionH > 0 && posPercentage >= 0 && posPercentage <= 100)
            {
                scrollPos = (int)(((float)maxPositionH * (float)posPercentage)/100);
            }
            else if(posPercentage > 100)
            {
                scrollPos = maxPositionH;
            }
            else
            {
                scrollPos = 0;
            }  
     
            this.getHorizontalScrollBar().setValue(scrollPos);
        }
     
        /*
         * Gets vertical scroll position in percentage
         */
        public final int getVerticalScrollPosition()
        {
            int maxPositionV = this.getVerticalScrollBar().getMaximum () - this.getVerticalScrollBar().getVisibleAmount();;
            int scrollPos = this.getVerticalScrollBar().getValue();
     
            int percentage = 0;
     
            if(maxPositionV > 0)
            {
                percentage = (int)(((float)scrollPos / (float)maxPositionV)*100);
            }
     
            return percentage;
        }
     
        public final void setVerticalScrollPosition(int posPercentage)
        {
            int maxPositionV = this.getVerticalScrollBar().getMaximum () - this.getVerticalScrollBar().getVisibleAmount();
            int scrollPos = this.getVerticalScrollBar().getValue();
     
            if(maxPositionV > 0 && posPercentage >= 0 && posPercentage <= 100)
            {
                scrollPos = (int)(((float)maxPositionV * (float)posPercentage)/100);
            }
            else if(posPercentage > 100)
            {
                scrollPos = maxPositionV;
            }
            else
            {
                scrollPos = 0;
            }   
     
            this.getVerticalScrollBar().setValue(scrollPos);
        }
     
        public final void setScrollPosition(int hPercentage, int vPercentage)
        {
            this.setHorizontalScrollPosition(hPercentage);
            this.setVerticalScrollPosition(vPercentage);
        }
     
        public void setZoom(float zoom)
        {
            this.picViewer1.setZoom(zoom);
     
            this.picViewer1.refreshImage();
     
            //Here I force to scroll (50%, 50%)
            this.setScrollPosition(50,50);
        }
     
        public void resize()
        {
            this.picViewer1.refreshImage();
        }
     
        public void refreshVisual()
        {
            this.picViewer1.refreshVisual();
     
            this.revalidate();
            this.repaint();
        }
     
        public void refreshImage()
        {
            this.picViewer1.refreshImage();
        }
     
    }

    c. PicViewer (JPanel)

    public class PicViewer extends javax.swing.JPanel
    {
        /**
         * Creates new form PicViewer
         */
        private Image imageOrg;
        private Image imageShown;
     
        private final int maxSize = 32000;
        private final int minSize = 1;
     
        private final float zoomMax = 5;
        private final float zoomMin = 0.1F;
     
        public PicViewer() 
        {
            initComponents();
     
            this.setLayout(new FlowLayout());
     
            this.setZoom(0.5F);    
            this.setBackground(Color.BLACK);
            this.setScaleImage(true);
        }
     
        protected void setSizeLimits()
        {
            if(this.getScaleImage() || (!this.getScaleImage() && this.imageShown == null))
            {    
                this.setMinimumSize(new Dimension(this.minSize, this.minSize));
                this.setMaximumSize(new Dimension(this.maxSize, this.maxSize));
            }
            else if(!this.getScaleImage() && this.imageShown != null)
            {
                int width = this.imageShown.getWidth(this);
                int height = this.imageShown.getHeight(this);
     
                this.setMinimumSize(new Dimension(width, height));
                this.setMaximumSize(new Dimension(width, height));
            } 
        }
     
        /**
         * Resizes and scales JPanel 
         */
        public void resize(int x, int y, int width, int height)
        {
            this.setSizeLimits();
     
            this.setPreferredSize(new Dimension(width, height));
            this.setBounds(x, y, width, height);
        }
     
        /**
         * Scales image using zoom ratio 
         */
        public void refreshImage()
        {   
            this.refreshImage(0, 0);
        }
     
        public void refreshImage(int posX, int posY)
        {   
            if(this.imageOrg != null)
            {
                float zoomLevel = this.getZoom();
     
                if(!this.getScaleImage())
                {
                    this.imageShown = this.imageOrg.getScaledInstance((int)(this.imageOrg.getWidth(this)*zoomLevel), (int)(this.imageOrg.getHeight(this)*zoomLevel), 0);
                }
                else if(this.getScaleImage())
                {
                    Component parent = this.getParent();
     
                    int parW = parent.getWidth();
                    int parH = parent.getHeight();
     
                    Dimension newDim = this.getScaledDimension(parW, parH);
     
                    if(newDim.width > 0 && newDim.height > 0)
                        this.imageShown = this.imageOrg.getScaledInstance(newDim.width, newDim.height, 0);
                }
     
                this.resize(posX, posY, this.imageShown.getWidth(this), this.imageShown.getHeight(this));
            }
        }
     
        protected Dimension getScaledDimension(int reqWidth, int reqHeight) 
        {
            int newWidth = 0;
            int newHeight = 0;
     
            float zoomLevel = this.getZoom();
            float localZoomLevel = 0;
     
            if(this.imageOrg != null)
            {
                int imgWidth = this.imageOrg.getWidth(this);
                int imgHeight = this.imageOrg.getHeight(this);
     
                if(reqWidth > reqHeight)
                {
                    localZoomLevel = (float)reqWidth/(float)imgWidth;
     
                    newWidth = reqWidth;
                    newHeight = (int)(imgHeight * localZoomLevel);
                }
                else
                {
                    localZoomLevel = (float)reqHeight/(float)imgHeight;
     
                    newHeight = reqHeight;
                    newWidth = (int)(imgWidth * localZoomLevel);
                }
            }
     
            return new Dimension((int)(newWidth * zoomLevel), (int)(newHeight * zoomLevel));
        }
     
        public void refreshVisual()
        {
            this.revalidate();
            this.repaint();
        }
     
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Dimension dim = this.getPreferredSize();
            g.drawImage(this.imageShown, 0, 0, dim.width, dim.height, null);
        }
     
        /*public void paint(Graphics g) 
        {
            super.paint(g);
            //Insets insets = getInsets();
            g.drawImage(this.imageShown, 0, 0, null);
        }*/
     
        @Override
        public void update(Graphics g)
        {
            super.update(g);
            this.paint(g);
        }        
    }

  7. #7
    Junior Member
    Join Date
    Jan 2013
    Posts
    13
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: JScrollPane and programatic scrolling

    Hello again!
    Thank you for your time.

    I did it! The problem lies in Netbeans designer. When I put my PicViewer into JScrollPane NetBeans is making some kind of constraints which don't allow to scroll properly. I deleted it from designer and I have added it manually in code and it works.
    Last edited by brajan1984; January 10th, 2013 at 07:07 AM. Reason: Posting code again because I don't see my last post...

Similar Threads

  1. Drag and drop scrolling problem
    By Jack_Maloney in forum AWT / Java Swing
    Replies: 1
    Last Post: January 18th, 2012, 08:23 PM
  2. Replies: 1
    Last Post: July 20th, 2011, 08:03 AM
  3. scrolling in jsp tables
    By ravindraneeluri in forum Member Introductions
    Replies: 1
    Last Post: May 25th, 2011, 09:17 AM
  4. Clipping while scrolling
    By copeg in forum AWT / Java Swing
    Replies: 0
    Last Post: May 24th, 2010, 09:37 PM
  5. JScrollPane
    By MysticDeath in forum AWT / Java Swing
    Replies: 1
    Last Post: February 17th, 2010, 10:21 PM