📄 friendselectshell.java
字号:
/*
* LumaQQ - Java QQ Client
*
* Copyright (C) 2004 luma <stubma@163.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package edu.tsinghua.lumaqq.ui;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import edu.tsinghua.lumaqq.IconHolder;
import edu.tsinghua.lumaqq.events.FriendSelectionEvent;
import edu.tsinghua.lumaqq.events.IFriendSelectionListener;
import edu.tsinghua.lumaqq.models.ClusterModel;
import edu.tsinghua.lumaqq.models.FriendModel;
import edu.tsinghua.lumaqq.models.GroupModel;
import edu.tsinghua.lumaqq.models.MobileModel;
import edu.tsinghua.swt.models.ShutterModel;
/**
* <pre>
* 把好友显示在树状图中供用户选择的窗口,每当一个好友被选择时,其会
* 触发一个好友选择事件,事件类是FriendSelectionEvent
* </pre>
*
* @author 马若劼
*/
public class FriendSelectShell implements ControlListener {
private Shell shell;
private Shell parent;
private Display display;
private IconHolder icons;
// 界面控件
private Tree tree;
// 事件监听器
private List listeners;
// 是否单选模式
private boolean single;
/**
* 构造函数
*
* @param parent
* 父窗口
* @param single
* true表示单选模式
*/
public FriendSelectShell(Shell parent, boolean single) {
this.parent = parent;
display = parent.getDisplay();
shell = new Shell(parent, SWT.BORDER | SWT.RESIZE);
// 添加自己为parent的监听器以能够在parent改变位置的时候也改变位置
parent.addControlListener(this);
// 初始化变量
icons = IconHolder.getInstance();
listeners = new ArrayList();
this.single = single;
// 初始化窗口布局
initLayout();
}
/**
* 设置窗口的位置,使其附着在父窗口旁
*/
private void setLocation() {
Rectangle bound = parent.getBounds();
shell.setLocation(bound.x + bound.width, bound.y);
}
/**
* 设置窗口的大小
*/
private void setSize() {
Point parentSize = parent.getSize();
shell.setSize(200, parentSize.y);
}
/**
* 多选择模式时的选择事件处理方法
*
* @param e
*/
private void multiSelectedMode(SelectionEvent e) {
// 产生List对象
List models = new ArrayList();
// 得到被选择的model
TreeItem ti = (TreeItem)e.item;
Object modelObj = ti.getData();
// 检查model的类型
if(modelObj instanceof FriendModel ||
modelObj instanceof MobileModel) {
models.add(modelObj);
FriendSelectionEvent event = new FriendSelectionEvent(models);
if(ti.getChecked())
fireFriendSelectedEvent(event);
else
fireFriendDeselectedEvent(event);
} else {
if(ti.getChecked()) {
// 把它的孩子都设为check状态
TreeItem[] children = ti.getItems();
if(children != null) {
// 没有check的,我们才添加到list中
for(int i = 0; i < children.length; i++) {
if(!children[i].getChecked()) {
children[i].setChecked(true);
models.add(children[i].getData());
}
}
// 触发事件
FriendSelectionEvent event = new FriendSelectionEvent(models);
fireFriendSelectedEvent(event);
}
} else {
// 把它的孩子都设为uncheck状态
TreeItem[] children = ti.getItems();
if(children != null) {
// 已经check的,我们才添加到list中
for(int i = 0; i < children.length; i++) {
if(children[i].getChecked()) {
children[i].setChecked(false);
models.add(children[i].getData());
}
}
// 触发事件
FriendSelectionEvent event = new FriendSelectionEvent(models);
fireFriendDeselectedEvent(event);
}
}
}
}
/**
* 初始化窗口布局
*/
private void initLayout() {
// 好友树
shell.setLayout(new FillLayout());
tree = new Tree(shell, SWT.CHECK | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
tree.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if(e.detail == SWT.CHECK) {
if(single)
singleSelectedMode(e);
else
multiSelectedMode(e);
}
}
});
shell.layout();
}
/**
* 单选模式时的选择事件处理方法
*
* @param e
*/
private void singleSelectedMode(SelectionEvent e) {
// 得到被选择的model
TreeItem ti = (TreeItem)e.item;
Object modelObj = ti.getData();
// 检查model的类型
if(modelObj instanceof FriendModel ||
modelObj instanceof MobileModel) {
// 取消先前被选择的item
TreeItem[] items = tree.getItems();
for(int i = 0; i < items.length; i++) {
if(items[i] != ti)
items[i].setChecked(false);
TreeItem[] children = items[i].getItems();
for(int j = 0; j < children.length; j++)
if(children[j] != ti)
children[j].setChecked(false);
}
// 触发事件
List models = new ArrayList();
models.add(modelObj);
FriendSelectionEvent event = new FriendSelectionEvent(models);
if(ti.getChecked())
fireFriendSelectedEvent(event);
else
fireFriendDeselectedEvent(event);
} else {
ti.setChecked(false);
}
}
/**
* 设置Model,这将会用model中的数据重画树
* @param model
*/
public void setModel(ShutterModel model) {
StringBuffer sb = new StringBuffer();
int tabSize = model.getTabCount();
for(int i = 0; i < tabSize; i++) {
GroupModel g = (GroupModel)model.getTab(i);
if(g.isFriendly() && !g.isCluster()) {
// 每个组添加为一个根
TreeItem root = new TreeItem(tree, SWT.NONE);
root.setImage(icons.getImage(IconHolder.icoFolder));
root.setText(g.getName());
root.setData(g);
// 添加这个组的好友
int itemSize = model.getItemCount(i);
for(int j = 0; j < itemSize; j++) {
FriendModel f = (FriendModel)model.getItem(i, j);
// 生成叶子节点
TreeItem ti = new TreeItem(root, SWT.NONE);
// 设置图像
int face = f.getHeadId();
ti.setImage(icons.getSmallHead(face));
// 设置文字
sb.delete(0, sb.length());
sb.append(f.getQQ());
sb.append(" (");
sb.append(f.getName());
sb.append(')');
ti.setText(sb.toString());
// 把model添加到TreeItem中
ti.setData(f);
}
}
}
}
/**
* 设置手机好友model,如果不需要选择手机好友,则不需设置
*
* @param model
* 手机好友model
*/
public void setMobileModel(ShutterModel model) {
GroupModel g = (GroupModel)model.getTab(0);
TreeItem root = new TreeItem(tree, SWT.NONE);
root.setImage(icons.getImage(IconHolder.icoMobile));
root.setText(g.getName());
root.setData(g);
// 生成叶子节点
int tabSize = model.getItemCount(0);
for(int i = 0; i < tabSize; i++) {
MobileModel mm = (MobileModel)model.getItem(0, i);
TreeItem ti = new TreeItem(root, SWT.NONE);
ti.setText(mm.getName());
ti.setImage(mm.getImage());
ti.setData(mm);
}
}
/**
* 设置群model,把群里面的成员添加到树中
* @param c
*/
public void setClusterModel(ClusterModel c) {
TreeItem root = new TreeItem(tree, SWT.NONE);
root.setImage(icons.getSmallClusterHead(c.getFaceId()));
root.setText(c.getName());
root.setData(c);
StringBuffer sb = new StringBuffer();
Map members = c.getMembers();
Iterator i = members.values().iterator();
while(i.hasNext()) {
FriendModel f = (FriendModel)i.next();
// 生成叶子节点
TreeItem ti = new TreeItem(root, SWT.NONE);
// 设置图像
int face = f.getHeadId();
ti.setImage(icons.getSmallHead(face));
// 设置文字
sb.delete(0, sb.length());
sb.append(f.getQQ());
sb.append(" (");
sb.append(f.getName());
sb.append(')');
ti.setText(sb.toString());
// 把model添加到TreeItem中
ti.setData(f);
}
root.setExpanded(true);
}
/**
* 添加好友选择事件监听器
* @param listener
*/
public void addFriendSelectionListener(IFriendSelectionListener listener) {
listeners.add(listener);
}
/**
* 除去好友选择事件监听器
* @param listener
*/
public void removeFriendSelectionListener(IFriendSelectionListener listener) {
listeners.remove(listener);
}
/**
* 触发一个好友被选择的事件,事件的source是个FriendModel
* @param e
*/
private void fireFriendSelectedEvent(FriendSelectionEvent e) {
Iterator iter = listeners.iterator();
while(iter.hasNext())
((IFriendSelectionListener)iter.next()).friendSelected(e);
}
/**
* 触发一个好友被取消选择事件,source是一个FriendModel
* @param e
*/
private void fireFriendDeselectedEvent(FriendSelectionEvent e) {
Iterator iter = listeners.iterator();
while(iter.hasNext())
((IFriendSelectionListener)iter.next()).friendDeselected(e);
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.ControlListener#controlMoved(org.eclipse.swt.events.ControlEvent)
*/
public void controlMoved(ControlEvent e) {
setLocation();
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.ControlListener#controlResized(org.eclipse.swt.events.ControlEvent)
*/
public void controlResized(ControlEvent e) {
setLocation();
}
/**
* 隐藏或者显示窗口
* @param b
*/
public void setVisible(boolean b) {
if(b) {
setSize();
setLocation();
}
setLocation();
shell.setVisible(b);
}
/**
* @return true表示当前窗口可见
*/
public boolean isVisible() {
return shell.isVisible();
}
/**
* 把f代表的对象置为选择状态
*
* @param f
*/
public void select(Object f) {
if(f == null) return;
TreeItem[] roots = tree.getItems();
for(int i = 0; i < roots.length; i++) {
TreeItem[] tis = roots[i].getItems();
for(int j = 0; j < tis.length; j++) {
if(f.equals(tis[j].getData())) {
tis[j].setChecked(true);
return;
}
}
}
}
/**
* 选择一个根下所有的model
*
* @param obj
*/
public void selectFromRoot(Object obj) {
if(obj == null) return;
TreeItem[] roots = tree.getItems();
for(int i = 0; i < roots.length; i++) {
if(obj == roots[i].getData()) {
roots[i].setChecked(true);
TreeItem[] tis = roots[i].getItems();
for(int j = 0; j < tis.length; j++)
tis[j].setChecked(true);
return;
}
}
}
/**
* @return true如果窗口已经disposed
*/
public boolean isDisposed() {
return shell.isDisposed();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -