private void setupScrollBar() {
   if (is64Bit) {
     // 64-bit mode
     scrollBar =
         new HighPrecisionJScrollBar(
             Scrollbar.VERTICAL,
             new BigInteger(
                 1,
                 new byte[] {
                   (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                   (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
                 }),
             new BigInteger(
                 1,
                 new byte[] {
                   (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                   (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
                 }),
             new BigInteger(
                 1,
                 new byte[] {
                   (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
                   (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFC
                 }));
     scrollBar.setUnitIncrementHP(
         new BigInteger(
             1,
             new byte[] {
               (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
               (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x08
             }));
     scrollBar.setBlockIncrementHP(
         new BigInteger(
             1,
             new byte[] {
               (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
               (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x40
             }));
   } else {
     // 32-bit mode
     scrollBar =
         new HighPrecisionJScrollBar(
             Scrollbar.VERTICAL,
             new BigInteger(1, new byte[] {(byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00}),
             new BigInteger(1, new byte[] {(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}),
             new BigInteger(1, new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFC}));
     scrollBar.setUnitIncrementHP(
         new BigInteger(1, new byte[] {(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04}));
     scrollBar.setBlockIncrementHP(
         new BigInteger(1, new byte[] {(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x20}));
   }
   scrollBar.addChangeListener(
       new ChangeListener() {
         public void stateChanged(ChangeEvent e) {
           updateFromScrollBar();
         }
       });
 }
 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();
 }
 /** Makes the given address visible somewhere in the window */
 public void makeVisible(Address addr) {
   BigInteger bi = addressToBigInt(addr);
   scrollBar.setValueHP(bi);
 }