private void refreshDialog() {
    String nr = currentAccountNumber();
    accountcombo.removeAllItems();
    if (bank != null) {
      try {
        Set<String> s = bank.getAccountNumbers();
        ArrayList<String> accnumbers = new ArrayList<String>(s);
        Collections.sort(accnumbers);
        ignoreItemChanges = true;
        for (String item : accnumbers) {
          accountcombo.addItem(item);
          if (item.equals(nr)) accountcombo.setSelectedItem(item);
        }
        ignoreItemChanges = false;

        // clean up local accounts map
        for (String key : s) {
          if (!accounts.containsKey(key)) {
            accounts.put(key, bank.getAccount(key));
          }
        }
        Iterator<String> it = accounts.keySet().iterator();
        while (it.hasNext()) {
          if (!s.contains(it.next())) it.remove();
        }

        int size = s.size();
        btn_deposit.setEnabled(size > 0);
        btn_withdraw.setEnabled(size > 0);
        btn_transfer.setEnabled(size > 1);
        item_close.setEnabled(size > 0);

        for (BankTest t : tests) {
          JMenuItem m = testMenuItems.get(t);
          m.setEnabled(t.isEnabled(size));
        }

        updateCustomerInfo();
      } catch (Exception e) {
        error(e);
      }
    }
  }
  public BankGUI(BankDriver server) {
    this.driver = server;
    this.bank = server.getBank();

    if (server instanceof BankDriver2) {
      try {
        ((BankDriver2) server)
            .registerUpdateHandler(
                new BankDriver2.UpdateHandler() {
                  @Override
                  public void accountChanged(String number) {
                    SwingUtilities.invokeLater(
                        new Runnable() {
                          @Override
                          public void run() {
                            refreshDialog();
                          }
                        });
                  }
                });
      } catch (IOException e1) {
        throw new RuntimeException(e1);
      }
    }

    setTitle("ClientBank Application");
    setBackground(Color.lightGray);

    BankTest test;
    test = loadTest("bank.gui.tests.EfficiencyTest");
    if (test != null) {
      tests.add(test);
    }
    test = loadTest("bank.gui.tests.ThreadingTest");
    if (test != null) {
      tests.add(test);
    }
    test = loadTest("bank.gui.tests.FunctionalityTest");
    if (test != null) {
      tests.add(test);
    }
    test = loadTest("bank.gui.tests.TransferTest");
    if (test != null) {
      tests.add(test);
    }
    test = loadTest("bank.gui.tests.ConcurrentReads");
    if (test != null) {
      tests.add(test);
    }

    // define menus
    JMenuBar menubar = new JMenuBar();
    setJMenuBar(menubar);

    JMenu menu_file = new JMenu("File");
    menubar.add(menu_file);
    menu_file.add(item_new);
    menu_file.add(item_close);
    menu_file.addSeparator();
    menu_file.add(item_exit);

    JMenu menu_test = new JMenu("Test");
    menubar.add(menu_test);

    for (BankTest t : tests) {
      final BankTest tt = t;
      JMenuItem m = new JMenuItem(t.getName());
      testMenuItems.put(t, m);
      menu_test.add(m);
      m.addActionListener(
          new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              try {
                tt.runTests(BankGUI.this, bank, currentAccountNumber());
                refreshDialog();
              } catch (Exception ex) {
                error(ex);
              }
            }
          });
    }

    JMenu menu_help = new JMenu("Help");
    menubar.add(menu_help);
    menu_help.add(item_about);

    item_new.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            addAccount();
          }
        });
    item_close.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            closeAccount();
          }
        });
    item_exit.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            exit();
          }
        });
    item_about.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            about();
          }
        });

    addWindowListener(
        new WindowAdapter() {
          @Override
          public void windowClosing(WindowEvent e) {
            exit();
          }

          @Override
          public void windowDeiconified(WindowEvent e) {
            refreshDialog();
          }
        });

    accountcombo.addItemListener(
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            if (ignoreItemChanges) return;
            if (e.getStateChange() == ItemEvent.SELECTED) updateCustomerInfo();
          }
        });

    // create layout

    setResizable(false);

    JPanel center = new JPanel(new GridLayout(3, 2, 5, 5));
    center.add(new JLabel("Account Nr: ", SwingConstants.RIGHT));
    center.add(accountcombo);
    center.add(new JLabel("Owner: ", SwingConstants.RIGHT));
    center.add(fld_owner);
    center.add(new JLabel("Balance: ", SwingConstants.RIGHT));
    center.add(fld_balance);

    // set text fields read only
    fld_owner.setEditable(false);
    fld_balance.setEditable(false);

    JPanel east = new JPanel(new GridLayout(3, 1, 5, 5));
    east.add(btn_deposit);
    east.add(btn_withdraw);
    east.add(btn_transfer);

    JPanel p = new JPanel(new BorderLayout(10, 10));
    p.add(new JLabel(""), BorderLayout.NORTH);
    p.add(center, BorderLayout.CENTER);
    p.add(east, BorderLayout.EAST);
    if (!(driver instanceof BankDriver2)) {
      p.add(btn_refresh, BorderLayout.SOUTH);
    } else {
      p.add(new JLabel(""), BorderLayout.SOUTH);
    }
    add(p);

    // Add ActionListeners
    btn_refresh.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            refreshDialog();
          }
        });
    btn_deposit.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            deposit();
          }
        });
    btn_withdraw.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            withdraw();
          }
        });
    btn_transfer.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            transfer();
          }
        });

    Dimension d = accountcombo.getPreferredSize();
    d.setSize(Math.max(d.getWidth(), 130), d.getHeight());
    accountcombo.setPreferredSize(d);

    refreshDialog();
  }