This discussion is archived
12 Replies Latest reply: Oct 7, 2004 6:12 AM by 807587 RSS

Array of UnitIncrement

807587 Newbie
Currently Being Moderated
Hi,

I would like to set the unitIncrement of a horizontal scroll bar
in a JScrollPane so as it scrolls the view.
Until there, no prob.
However, the view is made of columns having different widths
thus I want to set unitIncrement to fit the column width that is going
to disappear (after the scroll) or apprear.
I thought about putting a listener on the scroll bar so that each time it is actionned
I can modify the unitIncrement, but that may not be the best way.
Would there be an easier/nicer way to do this ?

thanks
  • 1. Re: Array of UnitIncrement
    807587 Newbie
    Currently Being Moderated
    did I ask something silly ?

    regards
  • 2. Re: Array of UnitIncrement
    807587 Newbie
    Currently Being Moderated
    I looked around the api, and I don't see a way this can be done without using an AdjustmentListener to change the block increment..
  • 3. Re: Array of UnitIncrement
    807587 Newbie
    Currently Being Moderated
    I'm not sure the unit increment is going to be enough. It only sets one increment for forward and reverse scrolling. The sizes may be different for each. You might look around and see if you can find someone who has extended JScrollPane (??? my best guess right now) to ask the component it contains for the scrolling increment (which would probably mean a component which implements an interface to get preferred scrolling increments). All in all, this sounds like a lot of work.
  • 4. Re: Array of UnitIncrement
    807587 Newbie
    Currently Being Moderated
    If I make the JPanel containing my columns
    implement Scrollable, and especially :
    getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction)
    won't it do the trick ?

    thanks
  • 5. Re: Array of UnitIncrement
    807587 Newbie
    Currently Being Moderated
    If I make the JPanel containing my columns
    implement Scrollable, and especially :
    getScrollableUnitIncrement(Rectangle visibleRect, int
    orientation, int direction)
    won't it do the trick ?

    thanks
    Probably, but the best way to find out is to try it.
  • 6. Re: Array of UnitIncrement
    807587 Newbie
    Currently Being Moderated
    I'll do it and get back to you

    thanks
  • 7. Re: Array of UnitIncrement
    807587 Newbie
    Currently Being Moderated
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.table.*;
    
    public class MyTable extends JTable {
        public MyTable(int rows, int cols) {
            super(rows, cols);
        }
    
        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
            if (orientation == SwingConstants.VERTICAL)
                return super.getScrollableUnitIncrement(visibleRect, orientation, direction);
            else {
                int col = columnAtPoint(visibleRect.getLocation());
                Rectangle cell = getCellRect(0, col, true);
                if (cell.x == visibleRect.x) { //left side of viewport is on column edge ==> shift 1 column
                    if (direction<0)
                        col--;
                    if (col < 0)
                        return 0;
                    else
                        return getColumnModel().getColumn(col).getWidth();
                } else if (direction <0) //else left side of viewport divides column ==> shift the "rest"
                    return visibleRect.x - cell.x;
                else
                    return cell.x + cell.width - visibleRect.x;
            }
        }
    
        public static void main(String[] args) {
            JTable table = new MyTable(30,20);
            table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            TableColumnModel tcm = table.getColumnModel();
            for(int c=0, ub=tcm.getColumnCount(); c<ub; ++c)
                tcm.getColumn(c).setPreferredWidth(15*(c+1));
    
            JFrame f = new JFrame("MyTable");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.getContentPane().add(new JScrollPane(table));
            f.setSize(600, 400);
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    }
  • 8. Re: Array of UnitIncrement
    807587 Newbie
    Currently Being Moderated
    Hi,

    thanks for the code.
    Could not use it directly 'cause I did my own JTable,
    but it helped me.
    However, I have a problem with the visibleRect.
    I printed the visibleRect.getLocation(), each time the method
    is called.
    Initially, the scrollbar is to the max left.
    All my cells here have 29 of width.
    I have a JPanel of width 29 set as rowHeaderView
    Here is what I get, and I don't understand it.

    first click right scroll (first column disapear but that's what is printed)
    java.awt.Point[x=0,y=0]
    second click
    java.awt.Point[x=29,y=0]
    third click
    java.awt.Point[x=58,y=0]
    fourth
    java.awt.Point[x=87,y=0]
    the going back first click left and here is what I get !!!
    java.awt.Point[x=116,y=0]
    second click left
    java.awt.Point[x=87,y=0]
    third
    java.awt.Point[x=58,y=0]
    fourth and here I'm back at initial state (first column visible and scroll bar to the max)
    java.awt.Point[x=29,y=0]
    but another click gives me that :
    java.awt.Point[x=0,y=0]

    can someone help me ?

    thx
  • 9. Re: Array of UnitIncrement
    807587 Newbie
    Currently Being Moderated
    1. I'm a litttle surprised you can't use the code I gave, because I thought my getScrollableUnitIncrement
    was generic. Could you post your getScrollableUnitIncrement?

    2. As for your question about visibleRect.getLocation, the values you get do make sense: remember
    that they are the location before scrolling, so on your fifth click (when you start heading back), the
    location you see is the result of clicking right four times: 4x29=116, and the click that takes you
    back to the initial state show you x=29, because that is the location previous to shifting back to x=0.
  • 10. Re: Array of UnitIncrement
    807587 Newbie
    Currently Being Moderated
    Hi,

    thanks for your answer.
    Concerning your code, it is perfect but I'm not
    using JTable, I did my own so that why I could not directly
    use your code, but as I said it greatly helped me.
    Thanks for the explanation on the printed values.
    Understanding that, I'll see how to make it work.
    Will inform you.

    thanks
  • 11. Re: Array of UnitIncrement
    807587 Newbie
    Currently Being Moderated
    Ok,

    finalized the implem.
    Working perfectly except for :
    When I scroll to the far right I can't get back left !!!
    The "table" I have is made of 50 columns of width 28.
    The the JPanel implementing Scrollable has a width of 1400.
    The JScrollPane width is such that the last visible column
    is only partially visible.

    Here is the println of the last clicks.

    After the click leading to the following print the scroll
    bar is not completely to the right.
    java.awt.Rectangle[x=952,y=0,width=402,height=181]

    Scroll bar completely goes right and last column
    appears completely.
    java.awt.Rectangle[x=980,y=0,width=402,height=181]

    One more click, no visible effect but
    java.awt.Rectangle[x=998,y=0,width=402,height=181]

    any consecutive click to the right print the same above line.
    but then if I click left, I can't get back
    and is printed :
    java.awt.Rectangle[x=998,y=0,width=402,height=181]

    Note that it is also impossible to get back even if I don't do the last click
    to the right and then when clicking to the left I also get:
    java.awt.Rectangle[x=998,y=0,width=402,height=181]

    my code is the following :
    //the arrays of columns width that I store locally
    private int[] _columnsWidths;
    
    ....
    
      public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
    
        System.err.println(super.getPreferredSize());
        if(orientation == SwingConstants.VERTICAL)
          return MatrixTable._H;
        else {
          int col = columnAtPoint(visibleRect.getLocation());
          System.err.println(visibleRect);
          System.err.println(col);
          Rectangle cell = getCellRect(0, col, true);
          if (cell.x == visibleRect.x) { //left side of viewport is on column edge ==> shift 1 column
            if (direction<0)
              col--;
            if (col < 0)
              return 0;
            else
              return _columnsWidths[col];
          } else if (direction <0) //else left side of viewport divides column ==> shift the "rest"
            return visibleRect.x - cell.x;
          else
            return cell.x + cell.width - visibleRect.x;
        }
      }
    
      private int columnAtPoint(Point p) {
    
        int cummulatedWidth;
        int c;
    
        cummulatedWidth = 0;
        for(c = 0; c < _columnsWidths.length; c++) {
          if(cummulatedWidth >= p.x)
            break;
          cummulatedWidth += _columnsWidths[c];
        }
        return c;
      }
    
      private Rectangle getCellRect(int row, int col, boolean includeSpacing) {
    
        int cummulatedWidth;
        int c;
    
        cummulatedWidth = 0;
        for(c = 0; c < col; c++)
          cummulatedWidth += _columnsWidths[c];
        return new Rectangle(cummulatedWidth, row*MatrixTable._H, _columnsWidths[c], row*MatrixTable._H);
      }
    Where did I do wrong ?

    thanks
  • 12. Re: Array of UnitIncrement
    807587 Newbie
    Currently Being Moderated
    Hi,

    found my mistake.
    I should have written :
          if((cummulatedWidth + _columnsWidths[c]) > p.x)
            break;
    thank you very much.
    By the way could you help me for this question :

    http://forum.java.sun.com/thread.jsp?forum=57&thread=560920&tstart=0&trange=15