private void updateCursor(final String selection) {
   Cursor cursor = null;
   Class swtClass = SWT.class;
   if (selection != null) {
     try {
       Field field = swtClass.getField(selection);
       int cursorStyle = field.getInt(swtClass);
       cursor = Display.getCurrent().getSystemCursor(cursorStyle);
     } catch (Exception e) {
       e.printStackTrace();
     }
   }
   Iterator iter = controls.iterator();
   while (iter.hasNext()) {
     Control control = (Control) iter.next();
     control.setCursor(cursor);
   }
 }
 public Font getFont(Object element, int columnIndex) {
   if (columnIndex == 0) {
     return registry.getBold(Display.getCurrent().getSystemFont().getFontData()[0].getName());
   }
   return null;
 }
public class StationBrowserLayout {

  final Color red = Display.getCurrent().getSystemColor(SWT.COLOR_RED);
  final Color yellow = Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW);
  final Color white = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);

  private static SynClientSupport synClientSupport = new SynClientSupport();
  private static Shell shell;

  public Table table;
  public TableViewer tableViewer;
  StationData stationData = StationData.getInstance();
  static int pageSize; // 表格的每页所显示的记录条数
  static int row = 1; // 当前要显示的页

  public StationBrowserLayout() {
    super();
  }

  public StationBrowserLayout(Shell shell, MinaClient minaClient) {
    synClientSupport = minaClient.getSynClientSupport(); // 同步通信
    this.shell = shell;
    getStationInfo();
    pageSize = stationData.PAGE_SIZE;
  }

  public Composite create(Composite parentComp) {

    Composite comp = new Composite(parentComp, SWT.EMBEDDED);
    comp.setLayout(new MigLayout());
    createGroup(comp, "车站信息浏览", "pos 0.5al 0.2al", null);
    return comp;
  }

  private void createGroup(Composite parent, String title, String position, Object layout) {
    Group comp = new Group(parent, SWT.PUSH | SWT.NO_BACKGROUND | SWT.SHADOW_OUT);
    comp.setText(title.length() == 0 ? "\"\"" : title);
    comp.setLayoutData(layout != null ? layout : position);
    createComp(comp);
  }

  private void createComp(Composite group) {

    GridLayout layout = new GridLayout(1, false);
    layout.verticalSpacing = 10;
    group.setLayout(layout);

    // TableViewer是通过Table来布局的
    // 制作表格   MULTI可多选  H_SCROLL有水平 滚动条、V_SCROLL有垂直滚动条、BORDER有边框、FULL_SELECTION整行选择
    table = new Table(group, SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL); // 注意此处的设置
    TableLayout tableLayout = new TableLayout();
    table.setLayout(tableLayout);

    // 指定Table单元格的宽度和高度
    table.addListener(
        SWT.MeasureItem,
        new Listener() { // 向表格增加一个SWT.MeasureItem监听器,每当需要单元内容的大小的时候就会被调用。
          public void handleEvent(Event event) {
            event.width = table.getGridLineWidth(); // 设置宽度
            event.height =
                (int) Math.floor(event.gc.getFontMetrics().getHeight() * 1.5); // 设置高度为字体高度的1.5倍
          }
        });

    // 表格的视图
    tableViewer = new TableViewer(table);
    // 标题和网格线可见
    tableViewer.getTable().setLinesVisible(true);
    tableViewer.getTable().setHeaderVisible(true);
    // 设置填充
    // GridData data = new GridData(SWT.LEFT,SWT.CENTER, true, false);//SWT.FILL, SWT.FILL, true,
    // false  xbm
    GridData data = new GridData(GridData.FILL_BOTH);
    data.widthHint = 350;
    data.heightHint = 295;
    data.grabExcessHorizontalSpace = true;
    tableViewer.getTable().setLayoutData(data); // 表格的布局

    // 创建表格列的标题
    int width = 1;
    for (int i = 0; i < stationData.getColumnCount(); i++) {
      width = stationData.getColumnWidth(i);
      TableColumn column = new TableColumn(table, SWT.NONE);
      column.setWidth((int) (width * 8));
      column.setText(stationData.getColumnHeads()[i]); // 设置表头
      column.setAlignment(SWT.LEFT); // 对齐方式SWT.LEFT
      if (i == 0) // 站名
      {
        // 列的选择事件  实现排序
        column.addSelectionListener(
            new SelectionAdapter() {
              boolean sortType = true; // sortType记录上一次的排序方式,默认为升序

              public void widgetSelected(SelectionEvent e) {
                sortType = !sortType; // 取反。下一次排序方式要和这一次的相反
                tableViewer.setSorter(new StationSorter(sortType, stationData.columnHeads[0]));
              }
            });
      }
    }

    /*tableLayout.addColumnData(new ColumnWeightData(8, 8, false));//设置列宽为8像素
     TableColumn column_one = new TableColumn(table, SWT.NONE);//SWT.LEFT
     column_one.setText(stationData.COLUMN_HEADINGS[0]);//设置表头
     column_one.setAlignment(SWT.LEFT);//对齐方式SWT.LEFT
     column.setWidth(10);//宽度
    */

    // 设置标题的提供者
    tableViewer.setLabelProvider(new TableLabelProvider());

    // 设置表格视图的内容提供者
    tableViewer.setContentProvider(new TableContentProvider());

    // 设置列的属性.
    tableViewer.setColumnProperties(stationData.columnHeads);

    // 定义每一列的别名
    tableViewer.setColumnProperties(new String[] {"name", "down", "up", "map"});

    // 设置每一列的单元格编辑组件CellEditor
    CellEditor[] celleditors = new CellEditor[5];
    // 文本编辑框
    celleditors[0] = null;
    celleditors[1] = new TextCellEditor(table);
    celleditors[2] = new TextCellEditor(table);
    // CheckboxCellEditor(table) 复选框
    celleditors[3] = new ComboBoxCellEditor(table, StationData.MAPS, SWT.READ_ONLY); // 下拉框

    Text text = (Text) celleditors[1].getControl(); // 设置第down列只能输入数值
    text.addVerifyListener(
        new VerifyListener() {
          public void verifyText(VerifyEvent e) {
            // 输入控制键,输入中文,输入字符,输入数字 正整数验证
            Pattern pattern = Pattern.compile("[0-9]\\d*"); // 正则表达式
            Matcher matcher = pattern.matcher(e.text);
            if (matcher.matches()) // 处理数字
            {
              /*if(Integer.parseInt(e.text) != 0)//确保输入的数字不是0
              			e.doit = true;
              		else
              			e.doit = false;
              */
              e.doit = true;
            } else if (e.text.length() > 0) // 字符: 包含中文、空格
            e.doit = false;
            else // 控制键
            e.doit = true;
          }
        });

    Text text1 = (Text) celleditors[2].getControl(); // 设置第up列只能输入数值
    text1.addVerifyListener(
        new VerifyListener() {
          public void verifyText(VerifyEvent e) {
            String inStr = e.text;
            if (inStr.length() > 0) {
              e.doit = NumberUtils.isDigits(inStr);
            }
          }
        });

    table.addMouseMoveListener(
        new MouseMoveListener() {
          public void mouseMove(MouseEvent e) {
            if (StationData.reloadFlag) {
              getStationInfo();
              openCurrentTable(row);
              StationData.reloadFlag = false;
              // System.out.println("entry");
            }
          }
        });
    /*table.addFocusListener(new FocusListener(){
    public void focusGained(FocusEvent e) {
    	getStationInfo();
    	openCurrentTable(row);
    }
    @Override
    public void focusLost(FocusEvent e) {
    }
      });
         */
    tableViewer.setCellEditors(celleditors);

    // 设置单元的更改器
    tableViewer.setCellModifier(new TableCellModifier());

    tableViewer.addFilter(new TableViewerFilter()); // 过滤器

    // 构造工具条
    Composite buttonComposite = new Composite(group, SWT.NONE);
    buttonComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); // 使工具条居中
    Action actionModify =
        new Action("更新") {
          public void run() {
            // 取得用户所选择的第一行, 若没有选择则为null
            IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
            // 获取选中的第一行数据
            Station station = (Station) selection.getFirstElement();
            if (station != null) {
              if (updateStationInfo(
                  station.getStation_downnumber(),
                  station.getStation_upnumber(),
                  station.getStation_graph(),
                  station.getStation_name())) {
                showMsg("成功更新!");
                // 表格的刷新方法,界面会重新读取数据并显示

                pushCommand();

                tableViewer.refresh(); // false
              } else {
                showMsg("更新失败!");
                // tableViewer.refresh();//false
              }
            } else {
              showMsg("请选取进行更新的行!");
            }
          }
        };

    Action actionDelete =
        new Action("删除") {
          public void run() {
            // 取得用户所选择的第一行, 若没有选择则为null
            IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
            // 获取选中的第一个数据
            Station station = (Station) selection.getFirstElement();
            if (station != null) {
              // 先预先移动到下一行
              Table table = tableViewer.getTable();

              // int i = table.getSelectionIndex(); //取得当前所选行的序号,如没有则返回-1
              // table.setSelection(i + 1); //当前选择行移下一行
              // 确认删除
              MessageBox messageBox =
                  new MessageBox(shell, SWT.YES | SWT.NO | SWT.ICON_INFORMATION);
              messageBox.setText("提示信息");
              messageBox.setMessage("确定要删除此记录吗?");
              // SWT.YES 是  // SWT.NO 否 // SWT.CANCEL 取消 // SWT.RETRY 重试// SWT.ABORT 放弃// SWT.IGNORE
              // 忽略
              if (messageBox.open() == SWT.YES) {
                if (deleteStationInfo(station.getStation_name())) // 从数据库中删除记录
                {
                  // showMsg("成功删除!");
                  ((List) tableViewer.getInput()).remove(station); // 数据模型的List容器中删除
                  stationData.remove(station.getStation_name());
                  openCurrentTable(row);
                  tableViewer.remove(station); // 从表格界面上删除

                  pushCommand();
                } else showMsg("删除失败!");
              }
            } else {
              showMsg("请选取要删除的纪录!");
            }
          }
        };

    Action actionClear = new Action("清空") { // 清除所显示内容,点击保存后更新库
          public void run() {
            if (clearStationInfo()) {
              showMsg("清空操作成功!");
              stationData.removeAll();
              openCurrentTable(row);

              pushCommand();
            } else showMsg("清空操作失败!");
          }
        };
    Action actionHelp =
        new Action("帮助") {
          public void run() {
            String str = "更新:\n\r" + "先对某行内容进行修改,然后点击更新进行保存\n\r" + "清空:\n\r" + "从库中物理删除所有记录";
            showMsg(str);
          }
        };

    Action nextPage =
        new Action("下一页") {
          public void run() {
            row++;
            if (row > stationData.getTotalPageNum()) {
              row--;
              return;
            }
            openCurrentTable(row);
          }
        };
    Action prevPage =
        new Action("上一页") {
          public void run() {
            row--;
            if (row < 1) {
              row++;
              return;
            }
            openCurrentTable(row);
          }
        };

    Action refresh =
        new Action("刷新") {
          public void run() {
            getStationInfo();
            openCurrentTable(row);
          }
        };

    // 工具条
    ToolBar toolBar = new ToolBar(buttonComposite, SWT.FLAT | SWT.RIGHT); // |SWT.BORDER

    // 工具条管理器
    ToolBarManager manager = new ToolBarManager(toolBar);

    // manager.add(refresh);
    // manager.add(new Separator());

    manager.add(nextPage);
    manager.add(prevPage);

    manager.add(new Separator());

    manager.add(actionModify);
    manager.add(actionDelete);
    manager.add(actionClear);
    manager.add(new Separator());
    manager.add(actionHelp);
    manager.update(true);

    // 选中某行时,改变行的颜色
    table.addListener(
        SWT.EraseItem,
        new Listener() {
          public void handleEvent(Event event) {
            event.detail &= ~SWT.HOT;
            if ((event.detail & SWT.SELECTED) == 0) return;
            int clientWidth = table.getClientArea().width;
            GC gc = event.gc;
            Color oldForeground = gc.getForeground();
            Color oldBackground = gc.getBackground();
            gc.setForeground(red);
            // gc.setBackground(yellow);
            gc.fillGradientRectangle(0, event.y, clientWidth, event.height, false);
            gc.setForeground(oldForeground);
            gc.setBackground(oldBackground);
            event.detail &= ~SWT.SELECTED;
          }
        });

    // 在tableviewer内部为数据记录和tableItem之间的映射创建一个hash表,这样可以加快tableItem的和记录间的查找速度
    // 必须保证存在要显示的数据,否则程序出错。所以这里不能用下面的语句
    // tableViewer.setUseHashlookup(true);//必须在setInput之前加入才有效
    // 从服务器获取数据
    getStationInfo();
    // 通过setInput为table添加了一个list后,只要对这个list里的元素进行添加和删除,
    // table中的数据就会自动添加和删除,当然每次操作后需要调用refresh方法对tableviewer进行刷新。
    // 打开界面所显示的内容
    tableViewer.setInput(stationData.getData()); // 自动输入数据   即将数据显示在表格中
    tableViewer.setItemCount(stationData.PAGE_SIZE); // 设置显示的Item数
  } //// createComp

  /**
   * 通过将检索结果结合中的记录分页加载的方法,实现控制检索结果记录的分页显示与快速加载
   *
   * @param facttable 显示检索结果的GUI表格对象
   * @param pagenum 显示在表格对象中的检索结果页码,从1开始计算
   */
  private void openCurrentTable(final int pagenum) {

    table.clearAll(); // 清空表格所有项目中的数据
    // 数据记录在检索结果结合中的下标开始值
    final int recordstart = (pagenum - 1) * pageSize;
    // 当前表格能显示的最后一条记录在检索结果集合中的索引号
    int end = recordstart + pageSize;
    // 若表格可显示的记录大于检索结果记录的总数,就只显示到最后一条检索结果记录
    final int recordend = Math.min(end, stationData.getRowCount()); // 显示的最后一条记录在检索结果集合中的索引号

    // 当前页面显示的检索结果记录数
    final int currentdispnum = recordend - recordstart;
    // 根据当前的页码,从检索结果集合中加载相应的数据到表的item域中
    tableViewer.setInput(stationData.getRow(recordstart, recordstart + currentdispnum)); // 自动输入数据
    tableViewer.refresh(); // 刷新表格false
  }

  // 从服务器获取信息.
  private void getStationInfo() {
    SQLRequestMessage msg = new SQLRequestMessage();
    msg.setCommandMode(Constants.MODE_CS_SYN_CLIENT);
    msg.setCommandType(Constants.TYPE_CLIENT_SQLQUERY);
    msg.setDataBean("Station");

    // 不带参数的sql语句的使用方法
    msg.setSql("select * from Station order by Station_name "); // limit 16
    String paprams = "null"; //
    msg.setParams(paprams); // 转换为json字符串进行传递

    String listString = synClientSupport.sqlMessageSend(msg); // 同步通信
    if (listString == null) { // 此情况不会出现
      return;
    } else {
      List<Station> list = JsonUtil.getList4Json(listString, Station.class);
      if (list.size() <= 0) return;
      stationData.setData(list);
    }
  }

  private boolean clearStationInfo() { // 清空所有记录
    SQLRequestMessage msg = new SQLRequestMessage();
    msg.setCommandMode(Constants.MODE_CS_SYN_CLIENT);
    msg.setCommandType(Constants.TYPE_CLIENT_SQLBATCHDELETE);
    // 从一个表中进行删除操作
    /*
    msg.setCommandType(Constants.TYPE_CLIENT_SQLDELETE);
    msg.setDataBean("District");
    msg.setSql("delete from District");
    */
    String[] sqlArray = new String[6];
    sqlArray[0] = "delete from Station";
    sqlArray[1] = "delete from District";
    sqlArray[2] = "delete from Train";
    sqlArray[3] = "delete from StationDistrictRelation";
    sqlArray[4] = "delete from TrainDistrictRelation";
    sqlArray[5] = "delete from Plan";
    String sqlStr = JsonUtil.array2json(sqlArray);
    msg.setSql(sqlStr);

    String paprams = "null";
    msg.setParams(paprams);

    String list = synClientSupport.sqlMessageSend(msg);
    if (list == null) return false;
    else return true;
  }

  // 参数为车站ID
  // 所有相关的记录都将删除. ??????????????
  public boolean deleteStationInfo(String stationName) {
    SQLRequestMessage msg = new SQLRequestMessage();
    msg.setCommandMode(Constants.MODE_CS_SYN_CLIENT);

    // 从列车区段表District中获取车站ID等于stationID的所有区段的ID
    List<String> districtIDList = new ArrayList<String>();
    msg.setCommandType(Constants.TYPE_CLIENT_SQLQUERY);
    msg.setDataBean("District");
    String sqlStr =
        "select * from District where District_startstationname='"
            + stationName
            + "' or District_endstationname='"
            + stationName
            + "'";
    msg.setSql(sqlStr);
    String paprams = "null";
    msg.setParams(paprams);
    String listString = synClientSupport.sqlMessageSend(msg);
    if (listString == null) { // 此情况不会出现
      districtIDList = null;
    } else {
      List<District> list = JsonUtil.getList4Json(listString, District.class);
      if (list.size() <= 0) districtIDList = null;
      else {
        for (int i = 0; i < list.size(); i++) {
          District data = (District) list.get(i);
          districtIDList.add(data.getDistrict_name());
        }
      }
    }

    // 从列车表Train中获取车站ID等于stationID的所有车次的ID
    List<String> trainIDList = new ArrayList<String>();
    msg.setDataBean("Train");
    sqlStr =
        "select * from Train where Train_startstationname='"
            + stationName
            + "' or Train_endstationname='"
            + stationName
            + "'";
    msg.setSql(sqlStr);
    paprams = "null";
    msg.setParams(paprams);
    listString = synClientSupport.sqlMessageSend(msg);
    if (listString == null) { // 此情况不会出现
      trainIDList = null;
    } else {
      List<Train> list = JsonUtil.getList4Json(listString, Train.class);
      if (list.size() <= 0) trainIDList = null;
      else {
        for (int i = 0; i < list.size(); i++) {
          Train data = (Train) list.get(i);
          trainIDList.add(data.getTrain_name());
        }
      }
    }

    // 批量删除
    // 涉及到的表:Station, District Train StationDistrictRelation TrainDistrictRelation
    int districtNumber = 0;
    int trainNumber = 0;
    if (districtIDList != null) districtNumber = districtIDList.size();
    if (trainIDList != null) trainNumber = trainIDList.size();

    String[] sqlArray = new String[5 + districtNumber * 2 + trainNumber];

    int index = 0;

    sqlArray[index++] = "delete from Station where Station_name='" + stationName + "'"; // number 1
    sqlArray[index++] =
        "delete from StationDistrictRelation where Station_name='" + stationName + "'"; // number 1
    sqlArray[index++] =
        "delete from Plan where Station_name='"
            + stationName
            + "' or Prestation_name='"
            + stationName
            + "'"; // number 1

    if (districtIDList != null) {
      sqlArray[index++] =
          "delete from District where District_startstationname='"
              + stationName
              + "' or District_endstationname='"
              + stationName
              + "'"; // number 1
      for (int i = 0; i < districtNumber; i++) { // number districtNumber*2
        sqlArray[index++] =
            "delete from StationDistrictRelation where District_name='"
                + districtIDList.get(i)
                + "'";
        sqlArray[index++] =
            "delete from TrainDistrictRelation where District_name='" + districtIDList.get(i) + "'";
      }
    }
    if (trainIDList != null) {
      sqlArray[index++] =
          "delete from Train where Train_startstationname='"
              + stationName
              + "' or Train_endstationname='"
              + stationName
              + "'"; // number 1
      for (int i = 0; i < trainNumber; i++) { // number trainNumber
        sqlArray[index++] =
            "delete from TrainDistrictRelation where Train_name='" + trainIDList.get(i) + "'";
      }
    }
    msg.setCommandType(Constants.TYPE_CLIENT_SQLBATCHDELETE);
    sqlStr = JsonUtil.array2json(sqlArray);
    msg.setSql(sqlStr);
    paprams = "null";
    msg.setParams(paprams);

    listString = synClientSupport.sqlMessageSend(msg); // 同步通信
    if (listString == null) {
      return false;
    } else {
      return true;
    }
  }

  // 向服务器发送更新报文
  public boolean updateStationInfo(
      int downAvailLaneNum, int upAvailLaneNum, String map, String stationName) {
    SQLRequestMessage msg = new SQLRequestMessage();
    msg.setCommandMode(Constants.MODE_CS_SYN_CLIENT);
    msg.setCommandType(Constants.TYPE_CLIENT_SQLUPDATE);
    msg.setDataBean("Station");
    msg.setSql(
        "update Station set Station_downnumber=? ,"
            + "Station_upnumber=?,Station_graph=? where Station_name =?");
    if (downAvailLaneNum == 0) downAvailLaneNum = 1;
    if (upAvailLaneNum == 0) upAvailLaneNum = 1;
    Object[] params = new Object[] {downAvailLaneNum, upAvailLaneNum, map, stationName};
    String paprams = JsonUtil.array2json(params);
    msg.setParams(paprams);

    String list = synClientSupport.sqlMessageSend(msg); // 同步通信
    if (list == null) {
      return false;
    } else {
      return true;
    }
  }

  private void showMsg(String str) {
    MessageBox mb = new MessageBox(shell, SWT.ABORT | SWT.ICON_INFORMATION);
    mb.setText("提示信息"); // 消息框的标题
    mb.setMessage(str); // 消息框的提示文字
    mb.open();
  }

  // 通过替换过滤器来实现各种各样的过滤
  public class TableViewerFilter extends ViewerFilter {
    public boolean select(Viewer viewer, Object parentElement, Object element) {
      /* Station station = (Station) element;
      return p.getName().startsWith("张1");
      */
      return true;
    }
  }

  // 对指定列进行排序
  class StationSorter extends ViewerSorter {
    boolean direction = false; // 记录上一次的排序方式
    private int propertyIndex;

    public StationSorter(boolean direction, String sortByProperty) {
      this.direction = direction;
      for (int i = 0; i < (stationData.columnHeads).length; i++) {
        if (stationData.columnHeads[i].equals(sortByProperty)) {
          this.propertyIndex = i;
          return;
        }
      }
    }

    public int compare(Viewer viewer, Object e1, Object e2) {
      Station info1 = (Station) e1;
      Station info2 = (Station) e2;
      switch (propertyIndex) {
        case 0:
          // return info1.name.compareTo(info2.name);
          return direction
              ? info1.getStation_name().compareTo(info2.getStation_name())
              : info2.getStation_name().compareTo(info1.getStation_name());
          /*case 3:  对于checkcell
          if (bug1.isSolved == bug2.isSolved)
           return 0;
          if (bug1.isSolved)
           return 1;
          else
           return -1;*/
        default:
          return 0;
      }
    }
  }

  // 对单条记录进行处理
  /** 标签器方法返回的是各列的记录的文字 参数1:输入的对象 参数2:列号 返回值:注意一定要避免Null值,否则出错 */
  public class TableLabelProvider extends LabelProvider
      implements ITableLabelProvider, ITableFontProvider, ITableColorProvider {

    // 本方法用于显示图片
    public Image getColumnImage(Object element, int columnIndex) {
      /*
      Station station = (Station) element;
      // 只让“陈刚”这条记录显示图片
      if (station.getName().equals("陈刚") || station.getName().equals("周阅")) {
      	if (columnIndex == 0)// 第一列要显示的图片
      		return images[0];
      	if (columnIndex == 2)// 根据性别显示不同的图标
      		return o.isSex() ? images[1] : images[2];
      } */

      return null;
    }

    // 用于显示文字
    // getColumnText方法参数是1个object对象和需要写入数据的列数,返回一个String对象。他的作用相当于把每个字段的值写入到表格中
    /* 这里的element参数,其实就是我们二维数组中的每一个一维数组,其中保存的是
     * 每一行的所有数据,通过column这个参数依次写入到表格中的各个字段上。
     * column具体值是多少我们并不知道,因此需要我们来判断,并根据他里面的值
     * 来决定我们要将哪个数据返回。同样,该方法是不能返回NULL的。必须先检查数有效性。
     */
    public String getColumnText(Object element, int columnIndex) {
      Station station = (Station) element;
      if (station == null) // 解决表中空数据出现的错误
      return null;
      switch (columnIndex) {
        case 0:
          return station.getStation_name();
        case 1:
          return String.valueOf(station.getStation_downnumber());
        case 2:
          return String.valueOf(station.getStation_upnumber());
        case 3:
          return station.getStation_graph();
      }
      return null;
    }

    // 创建几个图像
    /*private Image[] images = new Image[] { new Image(null, "icons/22.jpg"), new Image(null, "icons/33.jpg"), new Image(null, "icons/44.jpg") };
    //当TableViewer对象被关闭时触发执行此方法
    public void dispose() {
       //SWT组件的原则:自己创建,自释放
      for (Image image : images) {
           image.dispose();
    }
    */
    // ITableFontProvider 对指定列设置字体
    FontRegistry registry = new FontRegistry();

    public Font getFont(Object element, int columnIndex) {
      if (columnIndex == 0) {
        return registry.getBold(Display.getCurrent().getSystemFont().getFontData()[0].getName());
      }
      return null;
    }
    // ITableColorProvide

    // 指定列变颜色
    public Color getBackground(Object element, int columnIndex) {
      if (columnIndex == 0) {
        return white;
      }
      return null;
    }

    public Color getForeground(Object element, int columnIndex) {
      if (columnIndex == 0) {
        return red;
      }
      return null;
    }

    private Color[] bg = new Color[] {red, white};
    private Color[] force = new Color[] {red, red};
    // 实现隔列换色
    /*
    public Color getForeground(Object element, int columnIndex) {
           return force[columnIndex%2];
       }
       public Color getBackground(Object element, int columnIndex) {
           return bg[columnIndex%2];
       }*/
    // 实现隔行换色
    /*	    private Object current = null;
        private int currentColor = 0;
        public Color getForeground(Object element, int columnIndex) {
            return force[currentColor];
        }
        public Color getBackground(Object element, int columnIndex) {
            if (current != element) {
                currentColor = 1 - currentColor;
                current = element;
            }
            return bg[currentColor];
        }
    */

  }

  // 通过接口IStructuredContentProvider和接口ITableLabelProvider将数据写入到表格中///
  // 如果让tableviewer显示数据,必须给它提供内容器和标签器,内容器的作用是从List(也可以是其他的集合类)中提取出一个对象
  // (例如People对应着表格的一行,数据库的一条记录),标签器的作用是从一个对象中提取出一个字段

  // 设置表格视图的内容器    对所有记录集中的记录进行处理
  public class TableContentProvider implements IStructuredContentProvider {
    // 接收到1个Object对象,这个Object对象可以是容器类对象或者数组,然后返回一个一维Object数组。
    // 他的作用就是通过传递进来的参数来自动设置表格中的数据需要占多少行

    // 这里的参数就是使用setInput()传进的参数
    public Object[] getElements(Object parent) {
      List results = new ArrayList();

      if (parent instanceof ArrayList) {
        results = (ArrayList) parent;
      }
      return results.toArray(); // 将List转化为数组
    }
    // 当TableViewer对象被关闭时触发执行此方法
    public void dispose() {
      //	System.out.println("Disposing ...");
    }
    // 当TableViewer再次调用setInput()时触发此方法执行
    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
      // System.out.println("Input changed: old=" + oldInput + ", new=" + newInput);

    }
  }

  // 设置单元的更改器
  class TableCellModifier implements ICellModifier {
    /* 是否可以修改此单元格。这里设置了任一单元格都可以修改。
     * @param element 表格记录对象
     * @param property 列的别名
     * 用来判断哪一个属性可写
     */
    public boolean canModify(Object element, String property) {
      // 根据每一行的对象动态显示ComboBoxCellEditor列表中的数据
      // 设置同一列的不同行中的下拉列表的内容不同
      // BusinessField 是一个实体类
      /*              BusinessField o = (BusinessField) element;
      String[] items=o.getFieldAttributes();
       tv.getCellEditors()[1]=new ComboBoxCellEditor(tv.getTable(), items, SWT.READ_ONLY);
       */
      return true;
    }
    /** 当单击单元格出现CellEditor时应该显示什么值。由此方法决定, 返回单元格的当前值 返回某个属性的值 */
    public Object getValue(Object element, String property) {
      Object result = null;
      Station station = (Station) element;
      if (station == null) return null;

      // 使用别名的方法
      if (property.equals("name")) return station.getStation_name();
      else if (property.equals("down")) return String.valueOf(station.getStation_downnumber());
      else if (property.equals("up")) return String.valueOf(station.getStation_upnumber());
      else if (property.equals("map")) // ComboBoxCellEditor要求返回下拉框中的索引值
      return new Integer(getNameIndex(station.getStation_graph()));

      // 直接使用索引
      /*  List list = Arrays.asList(stationData.columnHeads);
               int columnIndex = list.indexOf(property);
               //再返回对应的数据
               switch (columnIndex) {
               case 0://id
      	return String.valueOf(station.getStation_id());
      case 1://name
      	return station.getStation_name();
      case 2://down
      	return String.valueOf(station.getStation_downnumber());
      case 3://up
      	return String.valueOf(station.getStation_upnumber());
      case 4://map ,因为用的是下拉框,所以要返回一个Integer表示当前选中的index
      	return new Integer(getNameIndex(station.getStation_graph()));
               }
               */
      return result;
    }

    private int getNameIndex(String name) {
      for (int i = 0; i < StationData.MAPS.length; i++) {
        if (StationData.MAPS[i].equals(name)) return i;
      }
      return -1;
    }
    // 当用户对单元格内容进行修改 时,此方法执行. 为某个属性赋值
    public void modify(Object element, String property, Object value) {
      TableItem tableItem = (TableItem) element;
      if (tableItem == null) {
        // tableViewer.update(null, null);
        return;
      }
      Station station = (Station) tableItem.getData();
      if (station == null) {
        // tableViewer.update(null, null);
        return;
      }

      if (property.equals("name")) {
        String name = (String) value;
        station.setStation_name(name);
      } else if (property.equals("down")) {
        String down = (String) value;
        if (down.length() > 0) {
          station.setStation_downnumber(Integer.parseInt(down));
        }
      } else if (property.equals("up")) {
        String up = (String) value;
        if (up.length() > 0) {
          station.setStation_upnumber(Integer.parseInt(up));
        }
      } else if (property.equals("map")) {
        Integer comboIndex = (Integer) value;
        if (comboIndex.intValue() != -1) {
          String mapName = StationData.MAPS[comboIndex.intValue()];
          station.setStation_graph(mapName);
        }
      }

      // System.out.println("Modiy:" + value +"::"+columnIndex);
      /*List list = Arrays.asList(stationData.columnHeads);
       	  int columnIndex = list.indexOf(property);
       	  switch (columnIndex) {
       	  case 0:
       		  String id = (String) value;
       		  if (id.length() > 0) {
       			  station.setStation_id(Integer.parseInt(id));
       		  }
       		  break;
       	  case 1:
       		  String name = (String) value;
       		  if (name.length() > 0) {
       			  station.setStation_name(name);
       		  }
       		  break;

       	  case 2:
       		  String down = (String) value;
       		  if (down.length() > 0) {
       			  station.setStation_downnumber(Integer.parseInt(down));
       		  }
       		  break;
       	  case 3:
       		  String up = (String) value;
       		  if (up.length() > 0) {
       			  station.setStation_upnumber(Integer.parseInt(up));
       		  }
       		  break;
        	case 4:
        	   Integer comboIndex = (Integer) value;
              if(comboIndex.intValue() != -1){
           	  String mapName = StationData.MAPS[comboIndex.intValue()];
        station.setStation_graph(mapName);
       }
       break;
      }
      */
      tableViewer.update(station, null);
    }
  }

  private void pushCommand() {
    TrainData.initial();
    DistrictData.initial();
    StationData.reloadFlag = true;
    DistrictStationData.initial();
    // DistrictStationData.reloadFlag = true;
  }
}
  /**
   * Creates the dialog's contents
   *
   * @param shell the dialog window
   */
  private void createContents(final Shell shell) {

    final Config config = controller.getConfig();

    // Create the ScrolledComposite to scroll horizontally and vertically
    ScrolledComposite sc = new ScrolledComposite(shell, SWT.H_SCROLL | SWT.V_SCROLL);

    // Create the parent Composite container for the three child containers
    Composite container = new Composite(sc, SWT.NONE);
    GridLayout containerLayout = new GridLayout(1, false);
    container.setLayout(containerLayout);
    shell.setLayout(new FillLayout());

    GridData data;
    data = new GridData(GridData.FILL_HORIZONTAL);
    data.heightHint = 50;
    data.widthHint = 400;

    // START TOP COMPONENT

    Composite topComp = new Composite(container, SWT.NONE);
    GridLayout layout = new GridLayout(1, false);
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    layout.verticalSpacing = 0;
    topComp.setLayout(layout);
    topComp.setLayoutData(data);

    Label blank = new Label(topComp, SWT.NONE);
    data = new GridData(GridData.FILL_HORIZONTAL);
    data.heightHint = 10;
    blank.setLayoutData(data);
    blank.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));

    // Show the message
    Label label = new Label(topComp, SWT.NONE);
    label.setText(message);
    data = new GridData(GridData.FILL_HORIZONTAL);
    data.heightHint = 30;
    data.widthHint = 370;

    Font f = label.getFont();
    FontData[] farr = f.getFontData();
    FontData fd = farr[0];
    fd.setStyle(SWT.BOLD);
    label.setFont(new Font(Display.getCurrent(), fd));

    label.setLayoutData(data);
    label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));

    Label labelSeparator = new Label(topComp, SWT.SEPARATOR | SWT.HORIZONTAL);
    data = new GridData(GridData.FILL_HORIZONTAL);
    labelSeparator.setLayoutData(data);

    // END TOP COMPONENT

    // START MIDDLE COMPONENT

    Composite restComp = new Composite(container, SWT.NONE);
    data = new GridData(GridData.FILL_BOTH);
    restComp.setLayoutData(data);
    layout = new GridLayout(2, false);
    layout.verticalSpacing = 10;
    restComp.setLayout(layout);

    // Hide welecome screen
    Label labelHideWelcomeScreen = new Label(restComp, SWT.RIGHT);
    labelHideWelcomeScreen.setText(
        Labels.getString("AdvancedSettingsDialog.hideWelcomeScreen")); // $NON-NLS-1$
    labelHideWelcomeScreen.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));

    buttonHideWelcomeScreen = new Button(restComp, SWT.CHECK);
    buttonHideWelcomeScreen.setSelection(config.getBoolean(Config.HIDE_WELCOME_SCREEN));

    // batch size
    Label labelBatch = new Label(restComp, SWT.RIGHT);
    labelBatch.setText(Labels.getString("AdvancedSettingsDialog.batchSize")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelBatch.setLayoutData(data);

    textBatch = new Text(restComp, SWT.BORDER);
    textBatch.setText(config.getString(Config.LOAD_BATCH_SIZE));
    textBatch.setTextLimit(8);
    textBatch.addVerifyListener(
        new VerifyListener() {
          @Override
          public void verifyText(VerifyEvent event) {
            event.doit =
                Character.isISOControl(event.character) || Character.isDigit(event.character);
          }
        });
    data = new GridData();
    data.widthHint = 50;
    textBatch.setLayoutData(data);

    // insert Nulls
    Label labelNulls = new Label(restComp, SWT.RIGHT);
    labelNulls.setText(Labels.getString("AdvancedSettingsDialog.insertNulls")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelNulls.setLayoutData(data);
    buttonNulls = new Button(restComp, SWT.CHECK);
    buttonNulls.setSelection(config.getBoolean(Config.INSERT_NULLS));

    // assignment rules
    Label labelRule = new Label(restComp, SWT.RIGHT);
    labelRule.setText(Labels.getString("AdvancedSettingsDialog.assignmentRule")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelRule.setLayoutData(data);

    textRule = new Text(restComp, SWT.BORDER);
    textRule.setTextLimit(18);
    data = new GridData();
    data.widthHint = 115;
    textRule.setLayoutData(data);
    textRule.setText(config.getString(Config.ASSIGNMENT_RULE));

    // endpoint
    Label labelEndpoint = new Label(restComp, SWT.RIGHT);
    labelEndpoint.setText(Labels.getString("AdvancedSettingsDialog.serverURL")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelEndpoint.setLayoutData(data);

    textEndpoint = new Text(restComp, SWT.BORDER);
    data = new GridData();
    data.widthHint = 250;
    textEndpoint.setLayoutData(data);
    String endpoint = config.getString(Config.ENDPOINT);
    if ("".equals(endpoint)) { // $NON-NLS-1$
      endpoint = defaultServer;
    }

    textEndpoint.setText(endpoint);

    // reset url on login
    Label labelResetUrl = new Label(restComp, SWT.RIGHT);
    labelResetUrl.setText(
        Labels.getString("AdvancedSettingsDialog.resetUrlOnLogin")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelResetUrl.setLayoutData(data);
    buttonResetUrl = new Button(restComp, SWT.CHECK);
    buttonResetUrl.setSelection(config.getBoolean(Config.RESET_URL_ON_LOGIN));

    // insert compression
    Label labelCompression = new Label(restComp, SWT.RIGHT);
    labelCompression.setText(Labels.getString("AdvancedSettingsDialog.compression")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelCompression.setLayoutData(data);
    buttonCompression = new Button(restComp, SWT.CHECK);
    buttonCompression.setSelection(config.getBoolean(Config.NO_COMPRESSION));

    // timeout size
    Label labelTimeout = new Label(restComp, SWT.RIGHT);
    labelTimeout.setText(Labels.getString("AdvancedSettingsDialog.timeout")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelTimeout.setLayoutData(data);

    textTimeout = new Text(restComp, SWT.BORDER);
    textTimeout.setTextLimit(4);
    textTimeout.setText(config.getString(Config.TIMEOUT_SECS));
    textTimeout.addVerifyListener(
        new VerifyListener() {
          @Override
          public void verifyText(VerifyEvent event) {
            event.doit =
                Character.isISOControl(event.character) || Character.isDigit(event.character);
          }
        });
    data = new GridData();
    data.widthHint = 30;
    textTimeout.setLayoutData(data);

    // extraction batch size
    Label labelQueryBatch = new Label(restComp, SWT.RIGHT);
    labelQueryBatch.setText(Labels.getString("ExtractionInputDialog.querySize")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelQueryBatch.setLayoutData(data);

    textQueryBatch = new Text(restComp, SWT.BORDER);
    textQueryBatch.setText(config.getString(Config.EXTRACT_REQUEST_SIZE));
    textQueryBatch.setTextLimit(4);
    textQueryBatch.addVerifyListener(
        new VerifyListener() {
          @Override
          public void verifyText(VerifyEvent event) {
            event.doit =
                Character.isISOControl(event.character) || Character.isDigit(event.character);
          }
        });
    data = new GridData();
    data.widthHint = 30;
    textQueryBatch.setLayoutData(data);

    // enable/disable output of success file for extracts
    Label labelOutputExtractStatus = new Label(restComp, SWT.RIGHT);
    labelOutputExtractStatus.setText(
        Labels.getString("AdvancedSettingsDialog.outputExtractStatus")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelOutputExtractStatus.setLayoutData(data);

    buttonOutputExtractStatus = new Button(restComp, SWT.CHECK);
    buttonOutputExtractStatus.setSelection(config.getBoolean(Config.ENABLE_EXTRACT_STATUS_OUTPUT));

    // utf-8 for loading
    Label labelReadUTF8 = new Label(restComp, SWT.RIGHT);
    labelReadUTF8.setText(Labels.getString("AdvancedSettingsDialog.readUTF8")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelReadUTF8.setLayoutData(data);

    buttonReadUtf8 = new Button(restComp, SWT.CHECK);
    buttonReadUtf8.setSelection(config.getBoolean(Config.READ_UTF8));

    // utf-8 for extraction
    Label labelWriteUTF8 = new Label(restComp, SWT.RIGHT);
    labelWriteUTF8.setText(Labels.getString("AdvancedSettingsDialog.writeUTF8")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelWriteUTF8.setLayoutData(data);

    buttonWriteUtf8 = new Button(restComp, SWT.CHECK);
    buttonWriteUtf8.setSelection(config.getBoolean(Config.WRITE_UTF8));

    // European Dates
    Label labelEuropeanDates = new Label(restComp, SWT.RIGHT);
    labelEuropeanDates.setText(
        Labels.getString("AdvancedSettingsDialog.useEuropeanDateFormat")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelEuropeanDates.setLayoutData(data);

    buttonEuroDates = new Button(restComp, SWT.CHECK);
    buttonEuroDates.setSelection(config.getBoolean(Config.EURO_DATES));

    // Field truncation
    Label labelTruncateFields = new Label(restComp, SWT.RIGHT);
    labelTruncateFields.setText(Labels.getString("AdvancedSettingsDialog.allowFieldTruncation"));
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelTruncateFields.setLayoutData(data);

    buttonTruncateFields = new Button(restComp, SWT.CHECK);
    buttonTruncateFields.setSelection(config.getBoolean(Config.TRUNCATE_FIELDS));

    Label labelCsvCommand = new Label(restComp, SWT.RIGHT);
    labelCsvCommand.setText(Labels.getString("AdvancedSettingsDialog.useCommaAsCsvDelimiter"));
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelCsvCommand.setLayoutData(data);
    buttonCsvComma = new Button(restComp, SWT.CHECK);
    buttonCsvComma.setSelection(config.getBoolean(Config.CSV_DELIMETER_COMMA));

    Label labelTabCommand = new Label(restComp, SWT.RIGHT);
    labelTabCommand.setText(Labels.getString("AdvancedSettingsDialog.useTabAsCsvDelimiter"));
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelTabCommand.setLayoutData(data);
    buttonCsvTab = new Button(restComp, SWT.CHECK);
    buttonCsvTab.setSelection(config.getBoolean(Config.CSV_DELIMETER_TAB));

    Label labelOtherCommand = new Label(restComp, SWT.RIGHT);
    labelOtherCommand.setText(Labels.getString("AdvancedSettingsDialog.useOtherAsCsvDelimiter"));
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelOtherCommand.setLayoutData(data);
    buttonCsvOther = new Button(restComp, SWT.CHECK);
    buttonCsvOther.setSelection(config.getBoolean(Config.CSV_DELIMETER_OTHER));

    Label labelOtherDelimiterValue = new Label(restComp, SWT.RIGHT);
    labelOtherDelimiterValue.setText(
        Labels.getString("AdvancedSettingsDialog.csvOtherDelimiterValue"));
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelOtherDelimiterValue.setLayoutData(data);
    textSplitterValue = new Text(restComp, SWT.BORDER);
    textSplitterValue.setText(config.getString(Config.CSV_DELIMETER_OTHER_VALUE));
    data = new GridData();
    data.widthHint = 25;
    textSplitterValue.setLayoutData(data);

    // Enable Bulk API Setting
    Label labelUseBulkApi = new Label(restComp, SWT.RIGHT);
    labelUseBulkApi.setText(Labels.getString("AdvancedSettingsDialog.useBulkApi")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelUseBulkApi.setLayoutData(data);

    boolean useBulkAPI = config.getBoolean(Config.BULK_API_ENABLED);
    buttonUseBulkApi = new Button(restComp, SWT.CHECK);
    buttonUseBulkApi.setSelection(useBulkAPI);
    buttonUseBulkApi.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            super.widgetSelected(e);
            boolean enabled = buttonUseBulkApi.getSelection();
            // update batch size when this setting changes
            int newDefaultBatchSize = controller.getConfig().getDefaultBatchSize(enabled);
            logger.info("Setting batch size to " + newDefaultBatchSize);
            textBatch.setText(String.valueOf(newDefaultBatchSize));
            // make sure the appropriate check boxes are enabled or disabled
            initBulkApiSetting(enabled);
          }
        });

    // Bulk API serial concurrency mode setting
    Label labelBulkApiSerialMode = new Label(restComp, SWT.RIGHT);
    labelBulkApiSerialMode.setText(
        Labels.getString("AdvancedSettingsDialog.bulkApiSerialMode")); // $NON-NLS-1$
    labelBulkApiSerialMode.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));

    buttonBulkApiSerialMode = new Button(restComp, SWT.CHECK);
    buttonBulkApiSerialMode.setSelection(config.getBoolean(Config.BULK_API_SERIAL_MODE));
    buttonBulkApiSerialMode.setEnabled(useBulkAPI);

    // Bulk API serial concurrency mode setting
    Label labelBulkApiZipContent = new Label(restComp, SWT.RIGHT);
    labelBulkApiZipContent.setText(
        Labels.getString("AdvancedSettingsDialog.bulkApiZipContent")); // $NON-NLS-1$
    labelBulkApiZipContent.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));

    buttonBulkApiZipContent = new Button(restComp, SWT.CHECK);
    buttonBulkApiZipContent.setSelection(config.getBoolean(Config.BULK_API_SERIAL_MODE));
    buttonBulkApiZipContent.setEnabled(useBulkAPI);
    // timezone
    textTimezone =
        createTextInput(
            restComp,
            "AdvancedSettingsDialog.timezone",
            Config.TIMEZONE,
            TimeZone.getDefault().getID(),
            200);

    // proxy Host
    Label labelProxyHost = new Label(restComp, SWT.RIGHT);
    labelProxyHost.setText(Labels.getString("AdvancedSettingsDialog.proxyHost")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelProxyHost.setLayoutData(data);

    textProxyHost = new Text(restComp, SWT.BORDER);
    textProxyHost.setText(config.getString(Config.PROXY_HOST));
    data = new GridData();
    data.widthHint = 250;
    textProxyHost.setLayoutData(data);

    // Proxy Port
    Label labelProxyPort = new Label(restComp, SWT.RIGHT);
    labelProxyPort.setText(Labels.getString("AdvancedSettingsDialog.proxyPort")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelProxyPort.setLayoutData(data);

    textProxyPort = new Text(restComp, SWT.BORDER);
    textProxyPort.setText(config.getString(Config.PROXY_PORT));
    textProxyPort.setTextLimit(4);
    textProxyPort.addVerifyListener(
        new VerifyListener() {
          @Override
          public void verifyText(VerifyEvent event) {
            event.doit =
                Character.isISOControl(event.character) || Character.isDigit(event.character);
          }
        });
    data = new GridData();
    data.widthHint = 25;
    textProxyPort.setLayoutData(data);

    // Proxy Username
    Label labelProxyUsername = new Label(restComp, SWT.RIGHT);
    labelProxyUsername.setText(Labels.getString("AdvancedSettingsDialog.proxyUser")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelProxyUsername.setLayoutData(data);

    textProxyUsername = new Text(restComp, SWT.BORDER);
    textProxyUsername.setText(config.getString(Config.PROXY_USERNAME));
    data = new GridData();
    data.widthHint = 120;
    textProxyUsername.setLayoutData(data);

    // Proxy Password
    Label labelProxyPassword = new Label(restComp, SWT.RIGHT);
    labelProxyPassword.setText(
        Labels.getString("AdvancedSettingsDialog.proxyPassword")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelProxyPassword.setLayoutData(data);

    textProxyPassword = new Text(restComp, SWT.BORDER | SWT.PASSWORD);
    textProxyPassword.setText(config.getString(Config.PROXY_PASSWORD));
    data = new GridData();
    data.widthHint = 120;
    textProxyPassword.setLayoutData(data);

    // proxy NTLM domain
    Label labelProxyNtlmDomain = new Label(restComp, SWT.RIGHT);
    labelProxyNtlmDomain.setText(
        Labels.getString("AdvancedSettingsDialog.proxyNtlmDomain")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelProxyNtlmDomain.setLayoutData(data);

    textProxyNtlmDomain = new Text(restComp, SWT.BORDER);
    textProxyNtlmDomain.setText(config.getString(Config.PROXY_NTLM_DOMAIN));
    data = new GridData();
    data.widthHint = 250;
    textProxyNtlmDomain.setLayoutData(data);

    //////////////////////////////////////////////////
    // Row to start At

    Label blankAgain = new Label(restComp, SWT.NONE);
    data = new GridData();
    data.horizontalSpan = 2;
    blankAgain.setLayoutData(data);

    // Row to start AT
    Label labelLastRow = new Label(restComp, SWT.NONE);

    String lastBatch = controller.getConfig().getString(LastRun.LAST_LOAD_BATCH_ROW);
    if (lastBatch.equals("")) { // $NON-NLS-1$
      lastBatch = "0"; // $NON-NLS-1$
    }

    labelLastRow.setText(
        Labels.getFormattedString("AdvancedSettingsDialog.lastBatch", lastBatch)); // $NON-NLS-1$
    data = new GridData();
    data.horizontalSpan = 2;
    labelLastRow.setLayoutData(data);

    Label labelRowToStart = new Label(restComp, SWT.RIGHT);
    labelRowToStart.setText(Labels.getString("AdvancedSettingsDialog.startRow")); // $NON-NLS-1$
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    labelRowToStart.setLayoutData(data);

    textRowToStart = new Text(restComp, SWT.BORDER);
    textRowToStart.setText(config.getString(Config.LOAD_ROW_TO_START_AT));
    data = new GridData();
    data.widthHint = 75;
    textRowToStart.setLayoutData(data);
    textRowToStart.addVerifyListener(
        new VerifyListener() {
          @Override
          public void verifyText(VerifyEvent event) {
            event.doit =
                Character.isISOControl(event.character) || Character.isDigit(event.character);
          }
        });

    // now that we've created all the buttons, make sure that buttons dependent on the bulk api
    // setting are enabled or disabled appropriately
    initBulkApiSetting(useBulkAPI);

    // the bottow separator
    Label labelSeparatorBottom = new Label(restComp, SWT.SEPARATOR | SWT.HORIZONTAL);
    data = new GridData(GridData.FILL_HORIZONTAL);
    data.horizontalSpan = 2;
    labelSeparatorBottom.setLayoutData(data);

    // ok cancel buttons
    new Label(restComp, SWT.NONE);

    // END MIDDLE COMPONENT

    // START BOTTOM COMPONENT

    Composite buttonComp = new Composite(restComp, SWT.NONE);
    data = new GridData(GridData.HORIZONTAL_ALIGN_END);
    buttonComp.setLayoutData(data);
    buttonComp.setLayout(new GridLayout(2, false));

    // Create the OK button and add a handler
    // so that pressing it will set input
    // to the entered value
    Button ok = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
    ok.setText(Labels.getString("UI.ok")); // $NON-NLS-1$
    ok.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent event) {
            Config config = controller.getConfig();

            // set the configValues
            config.setValue(Config.HIDE_WELCOME_SCREEN, buttonHideWelcomeScreen.getSelection());
            config.setValue(Config.INSERT_NULLS, buttonNulls.getSelection());
            config.setValue(Config.LOAD_BATCH_SIZE, textBatch.getText());
            if (!buttonCsvComma.getSelection()
                && !buttonCsvTab.getSelection()
                && (!buttonCsvOther.getSelection()
                    || textSplitterValue.getText() == null
                    || textSplitterValue.getText().length() == 0)) {
              return;
            }
            config.setValue(Config.CSV_DELIMETER_OTHER_VALUE, textSplitterValue.getText());
            config.setValue(Config.CSV_DELIMETER_COMMA, buttonCsvComma.getSelection());
            config.setValue(Config.CSV_DELIMETER_TAB, buttonCsvTab.getSelection());
            config.setValue(Config.CSV_DELIMETER_OTHER, buttonCsvOther.getSelection());

            config.setValue(Config.EXTRACT_REQUEST_SIZE, textQueryBatch.getText());
            config.setValue(Config.ENDPOINT, textEndpoint.getText());
            config.setValue(Config.ASSIGNMENT_RULE, textRule.getText());
            config.setValue(Config.LOAD_ROW_TO_START_AT, textRowToStart.getText());
            config.setValue(Config.RESET_URL_ON_LOGIN, buttonResetUrl.getSelection());
            config.setValue(Config.NO_COMPRESSION, buttonCompression.getSelection());
            config.setValue(Config.TRUNCATE_FIELDS, buttonTruncateFields.getSelection());
            config.setValue(Config.TIMEOUT_SECS, textTimeout.getText());
            config.setValue(
                Config.ENABLE_EXTRACT_STATUS_OUTPUT, buttonOutputExtractStatus.getSelection());
            config.setValue(Config.READ_UTF8, buttonReadUtf8.getSelection());
            config.setValue(Config.WRITE_UTF8, buttonWriteUtf8.getSelection());
            config.setValue(Config.EURO_DATES, buttonEuroDates.getSelection());
            config.setValue(Config.TIMEZONE, textTimezone.getText());
            config.setValue(Config.PROXY_HOST, textProxyHost.getText());
            config.setValue(Config.PROXY_PASSWORD, textProxyPassword.getText());
            config.setValue(Config.PROXY_PORT, textProxyPort.getText());
            config.setValue(Config.PROXY_USERNAME, textProxyUsername.getText());
            config.setValue(Config.PROXY_NTLM_DOMAIN, textProxyNtlmDomain.getText());
            config.setValue(Config.BULK_API_ENABLED, buttonUseBulkApi.getSelection());
            config.setValue(Config.BULK_API_SERIAL_MODE, buttonBulkApiSerialMode.getSelection());
            config.setValue(Config.BULK_API_ZIP_CONTENT, buttonBulkApiZipContent.getSelection());

            controller.saveConfig();
            controller.logout();

            input = Labels.getString("UI.ok"); // $NON-NLS-1$
            shell.close();
          }
        });
    data = new GridData();
    data.widthHint = 75;
    ok.setLayoutData(data);

    // Create the cancel button and add a handler
    // so that pressing it will set input to null
    Button cancel = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
    cancel.setText(Labels.getString("UI.cancel")); // $NON-NLS-1$
    cancel.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent event) {
            input = null;
            shell.close();
          }
        });

    // END BOTTOM COMPONENT

    data = new GridData();
    data.widthHint = 75;
    cancel.setLayoutData(data);

    // Set the OK button as the default, so
    // user can type input and press Enter
    // to dismiss
    shell.setDefaultButton(ok);

    // Set the child as the scrolled content of the ScrolledComposite
    sc.setContent(container);

    // Set the minimum size
    sc.setMinSize(768, 1024);

    // Expand both horizontally and vertically
    sc.setExpandHorizontal(true);
    sc.setExpandVertical(true);
  }