简体   繁体   中英

Custom Swing Component and updating JScrollPane scrollbars

I have created a custom JComponent which draws text in paintComponent. Putting it in a ScrollPane I want to automatically display the scollbars when the appended text exceeds the viewport. When I resize the whole frame the scrollbars are updated correctly. But I would like to do it programmatically. I tried several #validate() and #invalidate() calls, but to no avail.

How do I update the scrollbars of a scrollpane with a custom component as client?

I created a simpified runnable example to show what I mean:

package swingscroll;

import java.awt.Color;
import java.awt.Dimension;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class SwingScroll {

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

    public static void createAndShowGUI() {
        final JFrame frame = new JFrame(SwingScroll.class.getSimpleName());
        final JComponent myComponent = new JComponent() {
            private Dimension preferredSize;

            @Override
            public void setPreferredSize(Dimension preferredSize) {
                super.setPreferredSize(preferredSize);
                this.preferredSize = preferredSize;
            }


            @Override
            public Dimension getPreferredSize() {
                return this.preferredSize;
            }

        };
        myComponent.setPreferredSize(new Dimension(380, 50));

        final JScrollPane scrollPane = new JScrollPane(myComponent);
        frame.getContentPane().add(scrollPane);

        frame.setSize(400, 100);
        frame.setVisible(true);

        // simulate the internal change of preferredSize in myComponent
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Logger.getLogger(SwingScroll.class.getName()).log(Level.SEVERE, null, ex);
                }
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        // this should trigger the scrollbar right?
                        myComponent.setPreferredSize(new Dimension(380, 1000));
                        // TODO insert code to update scrollbars
                    }
                });
            }
        }).start();
    }
}
// TODO insert code to update scrollbars
myComponent.revalidate();

just saw your comment:

When I add revalidate and repaint in my simple example the scrollbars still don't get updated.

Worksforme - though the problem with your example here is that the scrollbars are always showing, so it appears like nothing happens. Adjusting sizes so that there's really no vertical scrollbar initially and then update to a height that must show the bars is just fine.

BTW: I assume that the setPref in the example is just for demonstrating, not in production code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM