1

I need to handle event from JScrollPane when user scrolls it. In here it is suggested to use addAdjustmentListener to either JViewport or Vertical/HorizontalScrollBar.

Is there any difference, which method should I choose?

I would like also to use scrollRectToVisible for the same JScrollPane, should I anticipate AdjustmentListener working for this method?

Also I wonder whether scrollRectToVisible tries to do minimum scrolling to make required rectangular visible or it tries to make it visible in the middle of JViewport ?

UPD: Requirements:

1) There a JScrollPane with one JPanel which has many JLabel(ImageIcon), so some of them are not visible.

2) When a network event comes I need to show one of JLabel (make it visible) to user. If I is not visible originally then JScrollPane should scroll automatically. That's why I mention scrollRectToVisible.

3) Above that JLabel with ImageIcon inside I need to show a message which would explain what has happened to this element. The message currently is implemented as another JLabel with floats thanks to JLayeredPane much higher in hierarchy. The problem now is that if user scrolls JScrollPane that floating JLabel should move accordingly to be on top of correponding JLabel(ImageIcon).

UDP2: SSCCE

I have not implemented floating JLabel yet, but already I don't like how label with index 11 reacts to scrollRectToVisible since it is half cropped.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class JScrollPaneTest {
    protected ArrayList<JLabel> labels = new ArrayList<JLabel>();

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JScrollPaneTest();
            }
        });
    }

    public JScrollPaneTest() {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());

                JPanel panel1 = new JPanel ();

                panel1.setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();

                for (int i = 0; i < 20; i++) {
                    JLabel label = new JLabel("  | Label" + i + " |  ");
                    panel1.add(label, gbc);
                    labels.add(label);
                }

                panel1.addMouseListener(new MouseAdapter(){
                    public void mousePressed (MouseEvent me) {
                        JLabel label = labels.get(11);
                        label.scrollRectToVisible(label.getBounds());
                    }
                });

                JScrollPane pane = new JScrollPane(panel1) {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(600, 400);
                    }
                };

                pane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
                    @Override
                    public void adjustmentValueChanged(AdjustmentEvent e) {
                        System.out.println("adjustmentValueChanged: " + e);
                    }
                });

                frame.getContentPane().add(pane);

                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
Community
  • 1
  • 1
Nikolay Kuznetsov
  • 9,467
  • 12
  • 55
  • 101
  • could be depends if JComponent placed into JScrollPane has implemented scrollable – mKorbel Nov 28 '12 at 12:09
  • 1
    you really should start thinking in requirements (vs. assumed solutions): what _exactly_ do you want to achieve? – kleopatra Nov 28 '12 at 12:15
  • @kleopatra I have added requirements. – Nikolay Kuznetsov Nov 28 '12 at 13:30
  • @mKorbel, nope, it is just JPanel inside JScrollPane. – Nikolay Kuznetsov Nov 28 '12 at 13:31
  • ahh ... now it's much clearer :-) I would labelWithIcon.scrollRectToVisible(labelWithIcon.getBounds()) and then adjust the floating message to the new label coordinates (in the coordinates you use in the layeredPane) You might consider a SSCCE so we don't have to start from scratch in trying to help you :-) – kleopatra Nov 28 '12 at 13:37
  • @Nikolay Kuznetsov (especially for future readers) as mentioned (@kleopatra) post an SSCCE, there must be some small mistake returns wrong coordinates :-) – mKorbel Nov 28 '12 at 13:42
  • @mKorbel, SSCCE might come tomorrow. I am still in process of design how I should implement this functionality and many recent questions are related to it. Hopefully, this time coordinates would be okay. `SwingUtilities.convertPoint()` appeared to be extremely useful. – Nikolay Kuznetsov Nov 28 '12 at 13:46
  • @mKorbel, still I don't know where to add `AdjustmentListener` – Nikolay Kuznetsov Nov 28 '12 at 13:47
  • 1
    @Nikolay Kuznetsov derive JScrollBar from JScrollPane, btw did you check linked threads, hmmmm right, SwingUtilities.convertPoint() should be usefull to your previous question here, – mKorbel Nov 28 '12 at 13:54
  • 1
    @kleopatra, I have added SSCCE. – Nikolay Kuznetsov Nov 29 '12 at 12:10

1 Answers1

6

Part of the answer (code in comments is just ... and noticed I had it wrong in the comment ;-)

The method scrollRectToVisible takes a Rectangle in the coordinate system of the component it is called upon. To scroll a child such that it is completely visible, there are basically two options (use one of them):

// either call on child with zero offset
child.scrollRectToVisible(new Rectangle(child.getSize());
// or call on child's parent with child bounds
child.getParent().scrollRectToVisible(child.getBounds());
kleopatra
  • 51,061
  • 28
  • 99
  • 211