private void constrain() {
   BigInteger offset = new BigInteger(Integer.toString(addressSize * (numUsableRows)));
   BigInteger endVal = startVal.add(offset);
   if (endVal.compareTo(scrollBar.getMaximumHP()) > 0) {
     startVal = scrollBar.getMaximumHP().subtract(offset);
     endVal = scrollBar.getMaximumHP();
     scrollBar.setValueHP(startVal);
     model.fireTableDataChanged();
   }
 }
 private void recomputeNumVisibleRows() {
   Rectangle rect = new Rectangle();
   getBounds(rect);
   int h = table.getRowHeight();
   numVisibleRows = (rect.height + (h - 1)) / h;
   numUsableRows = numVisibleRows - 2;
   scrollBar.setBlockIncrementHP(new BigInteger(Integer.toString(addressSize * (numUsableRows))));
   model.fireTableDataChanged();
   // FIXME: refresh selection
 }
 private void updateFromScrollBar() {
   beginUpdate();
   BigInteger oldStartVal = startVal;
   startVal = scrollBar.getValueHP();
   constrain();
   model.fireTableDataChanged();
   if (oldStartVal != null) {
     modifySelection(oldStartVal.subtract(startVal).intValue() / addressSize);
   }
   endUpdate();
 }