public void openListShell() {

		if (null == listShell || listShell.isDisposed()) {
			listShell = new QQlistShell(clientSocket);
			//Display.getDefault().syncExec(listShell);
			new Thread(listShell).start();
			ShellManager.add(listShell);
			// change the height to fit the screen height
			int height = (int) Toolkit.getDefaultToolkit().getScreenSize()
					.getHeight();
			listShell.setSize(300, height);
			listShell.setText("QQ :" + loginUser.getQQnumber());
			// set location
			listShell.setLocation(new Point(0, 0));
			listShell.setImage(ImageManager.getImage(ImageManager.MINI_QQ));
			listShell.setLayout(new FillLayout());

			final TableViewer tableViewer = new TableViewer(listShell,
					SWT.SINGLE | SWT.V_SCROLL);

			tableViewer.setContentProvider(new ArrayContentProvider());
			tableViewer.setLabelProvider(new QQTableLabelProvider());

			tableViewer.setInput(loginService.getAllFriendArray());

			/*
			 * tableViewer.addSelectionChangedListener(new
			 * ISelectionChangedListener() {
			 * 
			 * @Override public void selectionChanged(SelectionChangedEvent
			 * event) { //Logger.log("selectchanged : "+event.getSelection());
			 * 
			 * } });
			 */
			tableViewer.addDoubleClickListener(new IDoubleClickListener() {

				@Override
				public void doubleClick(DoubleClickEvent event) {
					// TODO Auto-generated method stub
					StructuredSelection ss = (StructuredSelection) event
							.getSelection();
					User receiver = (User) ss.getFirstElement();
					Logger.log(receiver.getNickName().trim() + " : "
							+ receiver.getQQnumber().trim());
					openMsgShell(receiver);
				}
			});

			listShell.addShellListener(new ShellAdapter() {

				@Override
				public void shellClosed(ShellEvent e) {
					if (openedShellCount > 0)
						openedShellCount--;
					Logger.log("hide listShell...active shell: "
							+ openedShellCount);
					e.doit = false;
					listShell.setVisible(false);

				}
			});
			listShell.addDisposeListener(new DisposeListener() {

				@Override
				public void widgetDisposed(DisposeEvent e) {
					if (openedShellCount > 0)
						openedShellCount--;
					Logger.log("listShell disposed active shell: "
							+ openedShellCount);

				}
			});
			openedShellCount++;
			Logger.log("open listShell...active shell: " + openedShellCount);
			listShell.open();

			while (!listShell.isDisposed()) {
				if (!display.readAndDispatch()) {
					display.sleep();
				}
			}
		} else {

			openedShellCount++;
			Logger.log("open listShell...active shell: " + openedShellCount);
			listShell.setVisible(true);

		}

	}