Results 1 to 5 of 5
  1. #1
    kjkrum's Avatar
    kjkrum is offline Senior Member
    Join Date
    Apr 2011
    Location
    Tucson, AZ
    Posts
    1,060
    Rep Power
    6

    Default Making my JComponent scrollable

    I wrote a JComponent that uses tile-based drawing. Internally, it stores the tile information as an int[][]. It works very well.

    Now I want to use a larger tile array and make the visible area scrollable. My original idea was to have the component itself manage its own "position" within the tile array, and interact with its scroll bars by implementing AdjustmentListener. But this doesn't seem to fit into the existing pattern of JScrollPane.

    Would you recommend that I set the preferred size of my JComponent to the dimensions of the whole tile array, make it implement Scrollable, and let JScrollPane do the rest of the work?

    Do portions of a JComponent that are not visible in the JViewport exist as an image that consumes memory? My tile array may grow very large...
    Get in the habit of using standard Java naming conventions!

  2. #2
    DarrylBurke's Avatar
    DarrylBurke is online now Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,302
    Rep Power
    20

    Default Re: Making my JComponent scrollable

    Would you recommend that I set the preferred size of my JComponent to the dimensions of the whole tile array, make it implement Scrollable, and let JScrollPane do the rest of the work?
    Yes, with one difference: don't setPreferredSize, override getPreferredSize to return the appropriate Dimension. That insulates your class from an external call to getPreferredSize that could muck things up.

    Even in a situation that you want to allow external setting of preferredSize, I would still override getPreferredSize in a way similar to the JDK classes, making use of isPreferredSizeSet().

    Do portions of a JComponent that are not visible in the JViewport exist as an image that consumes memory? My tile array may grow very large...
    Huh? Portions of a JComponent that are visible don't exist as 'an image that consumes memory' so why should the non-visible parts?

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  3. #3
    kjkrum's Avatar
    kjkrum is offline Senior Member
    Join Date
    Apr 2011
    Location
    Tucson, AZ
    Posts
    1,060
    Rep Power
    6

    Default Re: Making my JComponent scrollable

    Thanks for the tips.

    I always assumed that JComponents were backed by some kind of Image, but evidently they are not. I also answered that part of my question experimentally with this silly program:

    Java Code:
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Rectangle;
    
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.Scrollable;
    import javax.swing.SwingUtilities;
    
    public class GiantComponent extends JComponent implements Scrollable {
    	private static final long serialVersionUID = 1L;
    	
    	public GiantComponent(int width, int height) {
    		setPreferredSize(new Dimension(width, height));
    	}
    
    	@Override
    	protected void paintComponent(Graphics g) {
    		super.paintComponent(g);
    		System.out.println("painting bounds: " + g.getClipBounds());
    	}
    
    	@Override
    	public Dimension getPreferredScrollableViewportSize() {
    		return new Dimension(640, 480);
    	}
    
    	@Override
    	public int getScrollableBlockIncrement(Rectangle arg0, int arg1, int arg2) {
    		// TODO Auto-generated method stub
    		return 0;
    	}
    
    	@Override
    	public boolean getScrollableTracksViewportHeight() {
    		// TODO Auto-generated method stub
    		return false;
    	}
    
    	@Override
    	public boolean getScrollableTracksViewportWidth() {
    		// TODO Auto-generated method stub
    		return false;
    	}
    
    	@Override
    	public int getScrollableUnitIncrement(Rectangle arg0, int arg1, int arg2) {
    		// TODO Auto-generated method stub
    		return 0;
    	}
    	
    	public static void main(String[] args) {
    		SwingUtilities.invokeLater(new Runnable() {
    
    			@Override
    			public void run() {
    				JFrame frame = new JFrame("Giant Scrollable Component");
    				JComponent component = new GiantComponent(1000000000, 1000000000);
    				JScrollPane scrollPane = new JScrollPane(component);
    				frame.getContentPane().add(scrollPane);				
    				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    				frame.pack();
    				frame.setResizable(false);
    				frame.setVisible(true);
    			}
    			
    		});
    	}
    }
    Get in the habit of using standard Java naming conventions!

  4. #4
    kjkrum's Avatar
    kjkrum is offline Senior Member
    Join Date
    Apr 2011
    Location
    Tucson, AZ
    Posts
    1,060
    Rep Power
    6

    Default Re: Making my JComponent scrollable

    I'm having trouble getting my JScrollPane to size itself correctly. The tutorial says in part:

    Unless you explicitly set a scroll pane's preferred size, the scroll pane computes it based on the preferred size of its nine components (the viewport, and, if present, the two scroll bars, the row and column headers, and the four corners). If the client is scrolling-savvy, then the scroll pane uses the value returned by the client's getPreferredScrollableViewportSize method to compute the size of its viewport.
    Here are the relevant parts of my JComponent.

    Java Code:
    	protected final Dimension viewportSize;
    
    	@Override
    	public Dimension getPreferredScrollableViewportSize() {
    		System.out.println("called getPreferredScrollableViewportSize()");
    		return viewportSize;
    	}
    
    	@Override
    	public Dimension getPreferredSize() {
    		Rectangle extents = buffer.getExtents();
    		int w = Math.max(extents.width, viewportSize.width);
    		int h = Math.max(extents.height, viewportSize.height);
    		System.out.println("preferred size: " + w + ", " + h);
    		return new Dimension(w, h);
    	}
    When I add my JComponent to a JScrollPane like this, the JFrame ends up with zero size. I can tell by my println that getPreferredScrollableViewportSize() is never called.

    Java Code:
    	JScrollPane scrollPane = new JScrollPane();
    	scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    	scrollPane.add(term); // my JComponent
    	frame.getContentPane().add(scrollPane);
    Why isn't getPreferredScrollableViewportSize() being called? What else do I need to do? I tried overriding isPreferredSizeSet(), but it seems to have no effect. If I add my JComponent directly to the JFrame's content pane, it works with or without overriding isPreferredSizeSet(). And if I add my JComponent to a JScrollPane, it doesn't work either way.
    Last edited by kjkrum; 03-11-2012 at 07:57 PM.
    Get in the habit of using standard Java naming conventions!

  5. #5
    kjkrum's Avatar
    kjkrum is offline Senior Member
    Join Date
    Apr 2011
    Location
    Tucson, AZ
    Posts
    1,060
    Rep Power
    6

    Default Re: Making my JComponent scrollable

    Oh, geez. Fixed it.

    Java Code:
    JScrollPane scrollPane = new JScrollPane();
    scrollPane.add(term);
    Should be

    Java Code:
    JScrollPane scrollPane = new JScrollPane(term);
    Get in the habit of using standard Java naming conventions!

Similar Threads

  1. Replies: 1
    Last Post: 03-03-2012, 09:35 PM
  2. Replies: 7
    Last Post: 09-23-2011, 08:04 PM
  3. Replies: 2
    Last Post: 10-01-2010, 07:18 PM
  4. SetBackground for JComponent
    By tulasi.neppali in forum AWT / Swing
    Replies: 5
    Last Post: 09-12-2010, 10:14 PM
  5. scrollable applets
    By kaemonsaionji in forum New To Java
    Replies: 2
    Last Post: 02-25-2009, 08:47 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •