jface

JFace 是建立在 SWT 之上的 UI 部件,它是 SWT 的扩展并能和SWT交互。

ApplicationWindow和Action

org.eclipse.jface.window.ApplicationWindow;

JFace为了简化窗口的设计特别设计了类,比如ApplicationWindow这一个类,它里面包含了六个默认方法,分别用于创建内容、菜单、工具栏、状态栏以及初始化和销毁。这样使整个程序的结构易于控制,而不是像单独用SWT开发时一切需要程序员自己实现。

ApplicationWindow创建窗体

窗体的布局 默认为网格式布局(GridLayout)
public class JFaceWindowsClass extends ApplicationWindow {
    JFaceWindowsClass() {
        //父类接受一个参数为Shell类的对象作为父窗口句柄,
        //如果这个窗口为顶级窗口的话,则传null
        super(null);
    }

    public void run() {
        //直到窗口关闭方能从 open()方法返回
        setBlockOnOpen(true);
        //打开窗口
        open();
        //关闭窗口时释放在操作系统中用到的资源
        Display.getCurrent().dispose();
    }

    //创建并放置窗口小部件
    public Control createContents(Composite parent) {
        // 设置窗体大小
        parent.getShell().setSize(500, 375);
        // 设置窗体标题
        parent.getShell().setText("JFace ApplicationWidows 实例");
        return parent;
    }

    public static void main(String[] args) {
        new JFaceWindowsClass().run();

    }
}

在 JFace 窗口添加 SWT 基本组件:createContents()

ApplicationWindow 将在所有其他窗口控件创建之后,窗口在屏幕上显示之前调用createContents方法。

ToolBarManager和MenuManger

    JFaceWindowsClass() {
        // 父类接受一个参数为Shell类的对象作为父窗口句柄,
        // 如果这个窗口为顶级窗口的话,则传null
        super(null);
        //在构造函数中调用addMenuBar和addToolBar让工具条和菜单显示出来
        addMenuBar();
        addToolBar(SWT.FLAT | SWT.WRAP);
    }

ToolBarManager 是对SWT的ToolBar控件的封装。

//构造方法
public ToolBarManager() 
public ToolBarManager(int style) 
public ToolBarManager(ToolBar toolbar)

一般我们都是向ToolBarManager里面添加Action,显示的效果就是一个Button

    //创建工具条
    @Override
    protected ToolBarManager createToolBarManager(int style) {
        ToolBarManager toolbar = new ToolBarManager();
        return toolbar;
    }

MenuManger
    //创建菜单
    @Override
    protected MenuManager createMenuManager() {
        MenuManager menubar = new MenuManager();
        MenuManager fileMenu = new MenuManager(" &File ");
        menubar.add(fileMenu);
        return menubar;
    }

1

现在这样还是没有效果的,要想有效果。还要加Action


自定义Action动作

action 通常被称为动作命令, 可以关联到菜单,工具条,以及按钮。action 允许共享多个控件触发代码从而消除冗余代码。

Action构造器
protected Action()
protected Action(String text) 
protected Action(String text,ImageDescriptor image) 
protected Action(String text,int style)

Action是jface中的一个概念,在jface中通过org.eclipse.jface.action中的Action和ActionContributionItem类实现了视图和处理代码的分离,这样无论何时用户触发了一个控件的事件,都会激活一个相应的Action类实例来进行时间处理。

Action的功能

Action里面最重要的方法是run(),它也是事件触发以后执行的代码。

public class NewAction extends Action {

	@Override
	public void run() {
		System.out.println("点击了 新建");
	}

	//新建文件
	public NewAction() {
		//设置该action的对应按钮上的文本和按钮风格
		super("新建",AS_PUSH_BUTTON);
		//设置提示标签
		setToolTipText("新建文件");
	}
}

调用了父类的构造函数,其中第一个参数是Action对应的文本,而第二个参数则是一个风格参数。

效果就是Action被附加在了一个按钮上面,而按钮上显示的文本就是新建


Action关联菜单和工具栏

修改上述JFaceWindowsClass类中的重载方法

	//创建工具条
	@Override
	protected ToolBarManager createToolBarManager(int style) {
		ToolBarManager toolbar = new ToolBarManager();
		toolbar.add(new NewAction());
		return toolbar;
	}

	//创建菜单
	@Override
	protected MenuManager createMenuManager() {
		MenuManager menubar = new MenuManager();
		MenuManager fileMenu = new MenuManager(" &File ");
		fileMenu.add(new NewAction());
		menubar.add(fileMenu);
		return menubar;
	}

运行后,长这样。

菜单和工具栏共用一个 Action ,无论是从菜单还是从工具栏执行都能实现文件新建

你可以直接点击工具栏的新建,如下:

也可以在菜单栏中 File-新建

不管点击哪个,都能触发我们刚自定义的NewAction类中的run方法


ActionContributionItem

Action 类似 SWT 的事件,但 Contribution 的功能更复杂,它包括两个主要的 Contribution 类: ContributionItem 类、 ContributionManager 类。
 Contribution直译:贡献、捐赠
其中 ContributionItem 类提供个别的 GUI 组件的触发行为。 ActionContributionItem 类是
ContributionItem 的子类,该类执行应用程序关联的 GUI 行为 (Action)。它并不设置组件在窗体的显现,而是通过 fill()方法实现

MessageDialog

MessageDialog的用法

MessageDialog的用法很简单,只需要一句话.

MessageDialog.openInfomation(shell,title,message);
MessageDialog.openConfirm(shell,title,message);
MessageDialog.openQuestion(shell,title,message);
MessageDialog.openError(shell,title,message);

这四个的不同之处有三点:
                                提示的图标、                  显示的按钮、                   返回值
openInfomation       类似i的图标                    一个确定                           void
openConfirm           问号图标                        确定和取消                        boolean
openQuestion         问号图标                        是和否                               boolean
openError               一个X的图标                   确定                                  void


确认信息对话框

信息提示对话框用来向用户显示提示性的信息,用户通过对话框上的按钮来对信息进行确认。

构造
public static boolean openConfirm(Shell parent, String title, String message)
//使用举例
MessageDialog.openConfirm(shell, "对话框","请确认信息");


提示信息对话框

构造
public static void openInformation(Shell parent, String title, String message)
//使用举例
MessageDialog.openInformation(shell, "对话框","提示信息");


错误信息提示对话框

构造
public static void openError(Shell parent, String title, String message)
//使用举例
MessageDialog.openError(shell, "对话框","错误信息");


输入值对话框

InputDialog第5个参数,对输入值进行验证类。IInputValidator接口的一个实例就行,
需要重写isValid()方法
 // 定义一个输入对话框
 InputDialog dlg = new InputDialog(shell, "InputDialog标题", "请输入XXX", "初始化值", null); 
 if (dlg.open() == InputDialog.OK) { 
	 //打印输入的值
	 System.out.println(dlg.getValue());
 }


重要

自定义对话框

自定义对话框是通过自定义一个类通过继承 Dialog 类来定制的。

org.eclipse.jface.dialogs.Dialog
public class CustomDialog extends Dialog { 
 ......
}

①设置标题栏名称

②设置窗体大小

自定义关闭事件


向导对话框

Wizard类

其他对话框

颜色选择对话框

字体选择对话框

文件选择对话框


TableViewer

TableViewer和Table

TableViewer构造
public TableViewer(Composite parent) 
public TableViewer(Composite parent,int style) 
public TableViewer(Table table)

TableViewer把Table组件作为一个实例变量,从而实现了对Table功能的扩展

public class TableViewer extends AbstractTableViewer {
    private Table table;
}

tableViewer.getTable()来获取封装的Table对象

使用TableViewer的好处在哪

将组件的数据和组件显示分离开来,例如,

将表格和表格中的数据分离开来,使用SWT的Table、TableColumn和TableItem空间展现表格,

而使用TabelViewer等查看器管理表格的数据。这种设计很大程度上简化了表格、树等复杂的UI编程


TableViewer使用

在得到由List装载的包含数据信息的实体类对象后,

接下来就是使用TableViewer来显示这些数据,实现过程一般要经过如下步骤:

第一步:创建一个TableViewer对象,并在构造函数中用式样设置好表格的外观,这与其他SWT组件的用法一样。

第二步:通过表格内含的Table对象设置布局方式,一般都使用TableViewer的专用布局管理器TableLayout。该布局方式将用来管理表格内的其他组件(如TableColumn表格列)。

第三步:用TableColumn类创建表格列

第四步:设置内容器和标签器。内容器和标签器是JFace组件中的重要概念,它们分别是IStructuredContentProvider、ITableLabelProvider两个接口的实现类,它们的作用就是定义好数据应该如何在TableViewer中显示

第五步:用TableViewer的setInput方法将数据输入到表格。


表格模型对象

表格模型对象。一般可以对应一个实体类。。也就是数据库的一条信息嘛

public class Student {
	private int stuNo;// 学号
	private String name;// 姓名
	private int age;// 年龄

	
	public Student(int stuNo, String name, int age) {
		super();
		this.stuNo = stuNo;
		this.name = name;
		this.age = age;
	}

	public int getStuNo() {
		return stuNo;
	}

	public void setStuNo(int stuNo) {
		this.stuNo = stuNo;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}

有了初始的数据,还需要使用setContentProvider方法为表格创建一个规则,使初始化的数据对象(如 Student类的list集合)转化为表格中的数据。


表格内容提供器IContentProvider

IContentProvider负责将setInput方法传入的对象转化为表格所需要的对象。

//必须实现三个方法
public class StudentTableContentProvider implements IStructuredContentProvider{


	//将初始化数据的入口对象转为表格使用的数组对象
	@Override
	public Object[] getElements(Object arg0) {
		//返回表格数组
		return ((List)arg0).toArray();
	}
	
	//释放对象时调用
	@Override
	public void dispose() {
		//先给空实现
	}
	
	//表格中数据改变时调用
	@Override
	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		//先给空实现
	}

}

上面三个方法


表格标签提供器ILabelProvider

TableViewer中的标签提供器主要负责每个单元格中文本和图标的显示

ITableLabelProvider接口要求实现getColumnText和getColumnImage两个主要的方法,

  • getColumnText返回指定单元格的显示文本
  • getColumnImage返回指定单元格的显示图标

getColumnText:

//对列表里的每一个model分别解析,以把数据应用到每一列
public String getColumnText(Object element, int columnIndex)

其中element表示单元格所在行的对象,columnIndex表示单元格所在的列,返回显示的文本

getColumnImage:
public Image getColumnImage(Object element, int columnIndex)

其中element表示单元格所在行的对象,columnIndex表示单元格所在的列,返回此单元格的显示图标

看着多,实际上都是Override方法,一键实现
public class StudentTableLabelProvider implements ITableLabelProvider {

	// 设置单元格显示的图标
	@Override
	public Image getColumnImage(Object element, int columnIndex) {
		// TODO Auto-generated method stub
		return null;
	}

	// 设置单元格显示的文本
	@Override
	public String getColumnText(Object element, int columnIndex) {
        //element
		Student stu=(Student)element;
		switch (columnIndex) {
		case 0:
			return stu.getStuNo()+"";//第一列

		case 1:
			return stu.getName();//第二列

		case 2:
			return stu.getAge()+"";//第三列

		}
		return null;
	}

	@Override
	public void addListener(ILabelProviderListener arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void dispose() {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean isLabelProperty(Object arg0, String arg1) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void removeListener(ILabelProviderListener arg0) {
		// TODO Auto-generated method stub

	}

}

setInput()表格初始化入口
void setInput(Object input)

setInput()方法是表格数据最初的入口点,任何对象都可以设置为表格数据,因为该方法所设
定的对象为Object对象,所有的类都是Object子类。但通常使用集合类来组织数据。

private TableViewer tv;
private Table table;

设置表格

        tv = new TableViewer(composite, SWT.FILL | SWT.BORDER | SWT.FULL_SELECTION);

        // 第二步:通过表格内含的Table对象设置布局方式
        table = tv.getTable();
        table.setHeaderVisible(true); // 显示表头
        table.setLinesVisible(true); // 显示表格线
        table.setHeaderBackground(SWTResourceManager.getColor(255, 239, 213));

设置表格列

        // 第三步:用TableColumn类创建表格列

        TableColumn Col1 = new TableColumn(table, SWT.NONE);
        Col1.setText(OBEJCTONE);
        Col1.setWidth(100);

        TableColumn Col2 = new TableColumn(table, SWT.NONE);
        Col2.setText(OPERATION);
        Col2.setWidth(150);

        TableColumn Col3 = new TableColumn(table, SWT.NONE);
        Col3.setText(OBEJCTTWO);
        Col3.setWidth(100);

        TableColumn Col4 = new TableColumn(table, SWT.NONE);
        Col4.setText(LINKCONDITION);
        Col4.setWidth(150);

设置内容提供器

        //设置内容提供器
        tv.setContentProvider(new MultiConditionTableContentProvider());


        //设置标签提供器
        tv.setLabelProvider(new MultiConditionTableLabelProvider());

表格初始化内容   

    //表格初始化内容
        ArrayList<ARCondition> arConditions = new ArrayList<>();
        tv.setInput(arConditions);


单元格编辑
   //调用自定义表格单元修改方法
   modifyTableViewerCell();

    // 自定义修改表格单元方法
    public void modifyTableViewerCell() {
        // 建立每一列的表格单元编辑器
        CellEditor[] editors = new CellEditor[4];
        editors[0] = null;//对象一,不可编辑
        editors[1] = new ComboBoxCellEditor(table, new String[]{"大于", "小于", "等于", "大于等于", "小于等于", "是否包含"}, SWT.READ_ONLY);//连接条件
        editors[2] = null;//对象二,,不可编辑
        editors[3] = new ComboBoxCellEditor(table, new String[]{"与", "或"}, SWT.READ_ONLY);//连接条件
        // 设置列属性
        tv.setColumnProperties(new String[]{OBEJCTONE, OPERATION, OBEJCTTWO, LINKCONDITION});
        // 设置表格单元的修改器
        tv.setCellModifier(new MultiConditionTableViewerCellModifier(tv));
        // 设置单元格的编辑器
        tv.setCellEditors(editors);
    }

对应类

public class MultiConditionTableViewerCellModifier implements ICellModifier {
    private Viewer viewer;

    public MultiConditionTableViewerCellModifier(Viewer viewer) {
        this.viewer = viewer;
    }

    /**
     * 检查给定元素的给定属性是否能被修改
     *
     * @param element  表格中一行的全部内容,并封装成一个对象
     * @param property 表格中的列名
     * @return
     */
    public boolean canModify(Object element, String property) {
        if (MultiConditionDialog.OBEJCTONE.equals(property))
            return false;
        else if (MultiConditionDialog.OPERATION.equals(property))
            return true;
        else if (MultiConditionDialog.OBEJCTTWO.equals(property))
            return false;
        else if (MultiConditionDialog.LINKCONDITION.equals(property))
            return true;
        return true;
    }

    /**
     * 返回给定元素的给定属性值
     *
     * @param element  表格记录的对象
     * @param property 表格列属性
     * @return
     */
    public Object getValue(Object element, String property) {
        ARCondition p = (ARCondition) element;
        if (MultiConditionDialog.OBEJCTONE.equals(property))
            return p.getObejctOne();
        else if (MultiConditionDialog.OPERATION.equals(property)){
            int idx = PaneRightRightImpl.findSelectIdx("判断条件", p.getOperation(), null);
            return new Integer(idx);
        }
        else if (MultiConditionDialog.OBEJCTTWO.equals(property))
            return p.getObejctTwo();
        else if (MultiConditionDialog.LINKCONDITION.equals(property)) {
            int idx = PaneRightRightImpl.findSelectIdx("逻辑条件", p.getLinkCondition(), null);
            return new Integer(idx);
        } else
            return null;
    }

    /**
     * 修改表格单元中的值
     *
     * @param element  表格记录的对象
     * @param property 表格列属性
     * @param value    修改的新值
     */
    @Override
    public void modify(Object element, String property, Object value) {
        TableItem tableItem = (TableItem) element;
        ARCondition p = (ARCondition) tableItem.getData();
        if (MultiConditionDialog.OBEJCTONE.equals(property))
            p.setObejctOne(value + "");
        else if (MultiConditionDialog.OPERATION.equals(property))
            p.setOperation(new String[]{"大于", "小于", "等于", "大于等于", "小于等于", "是否包含"}[(Integer) value]);
        else if (MultiConditionDialog.OBEJCTTWO.equals(property))
            p.setObejctTwo(value + "");
        else if (MultiConditionDialog.LINKCONDITION.equals(property)) {
            if (MultiConditionDialog.isBlank) {//点击的是最后一行,最后一列
                p.setLinkCondition("");
                MultiConditionDialog.isBlank=false;
            } else {
                p.setLinkCondition(new String[]{"与", "或"}[(Integer) value]);
            }
        }

        // 修改更新
        viewer.refresh();
    }
}


TreeViewer

树内容提供器ContentProvider

TreeViewer的内容提供器(ITreeContentProvider)构建树中比较复杂的部分,它为树的显示提供了内容,内容提供器要实现的方法如下。

1.  getElements

public Object[] getElements(Object inputElement);

当程序开始构建树时,首先调用getElements返回一个对象的数组,此数组对象表示当前树的根节点,inputElement参数为TreeViewer的输入(setInput的输入数据)。

--------------------------------------
2.  hasChildren

public boolean hasChildren(Object element);

当TreeViewer显示一个节点后,会调用hasChildren函数判断当前节点是否有子节点,如果有子节点则显示“+”,element参数为要判断是否有子节点的节点。

--------------------------------------
3.  getChildren

public Object[] getChildren(Object parentElement);

当用户选择节点打开子节点时,会调用getChildren函数返回下一层子节点,parentElement参数为选择的节点。
--------------------------------------

4.  getParent

public Object getParent(Object element);

可以通过此方法返回element的父节点。
--------------------------------------

5.  inputChanged

public void inputChanged(Viewer viewer, Object oldInput, Object newInput);

当输入改变时调用此方法。

--------------------------------------
6.  dispose

public void dispose();

当树销毁时被调用。

通过getElements方法得到根,再通过hasChildren判断根下是否有子节点,如果有子节点,可以通过getChildren得到所有的子节点


单元格可编辑


树标签提供器LabelProvider

树查看器使用的标签提供器为 ILabelProvider

ILabelProvider主要实现getImage和getText函数。当TreeViewer得到一个节点后会通过getText得到此节点的显示文本,通过getImage方法得到节点的显示图标


TreeViewer使用举例

构造器
TreeViewer(Composite parent) 
TreeViewer(Composite parent, int style) 
TreeViewer(Tree tree)

TreeViewer 通过 setContentProvider 方法设置内容提供器,这个方法继承自 AbstractTreeViewer ,通过 setLabelProvider 方法设置标签提供器,这个方法继承自 ColumnViewer 。 TreeViewer 类的使用主要围绕内容和标签提供器两个类来进行。


 TreeViewer 常用API

 editElement(Object element, int column)开始编辑给定元素。
 getCellEditors()获得这个树查看器的单元编辑器。
 getCellModifier()获得这个树查看器的单元修改器。
 getControl()获得与这个查看器相关的控件。
 getTree()获得树查看器的树控件。
 getExpanded(Item item)返回给定的 SWT 项是否展开或收缩。
 showItem(Item item)显示给定项。
 isExpandable(Object element)返回代表给定元素的树的节点是展开还是收缩。
 setSelection(List items)设置选择给定的列表项。
 setCellEditors(CellEditor[] editors)为树查看器设置单元格编辑器。
 removeAll(Control widget)从给定的控件中移除所有项。
 setCellModifier(ICellModifier modifier)为树查看器设置单元格修改器。
 setLabelProvider(IBaseLabelProvider labelProvider)设置标签提供器。
 setExpanded(Item node, boolean expand)设置给定项的展开状态。

1


SWT字体和图像

系统资源释放

字体、颜色、图像等系统资源,需要在程序中显示调用dispose方法释放资源。

判断控件是否被释放的方法是使用控件对象的isDisposed()方法,如果控件已经被释放。则返回true,否则返回false。


字体Font

显示的创建字体:

只使用Font 创建字体

//方式一  Courier是字体名称、10是字体大小、SWT.NORMAL表示正常字体 若SWT。BOLD则表示加粗
Font font1=new Font(Display.getCurrent(),"Courier",10,SWT.NORMAL);

---------------------

使用FontData创建字体

FontData携带字体信息,如字体名称、大小、样式...

使用举例

//方式二 FontData携带字体信息,如字体名称、大小...
FontData data=new FontData("Courier",18,SWT.NORMAL);
Font font2=new Font(Display.getCurrent(),data);

//创建一个Label,显示Hello World
Label label = new Label(shell, SWT.NONE);
label.setText("Hello World");
label.setFont(font2);

效果如下:

获取系统默认的字体:getSystemFont()

//创建一个Label,显示Hello World
Label label2 = new Label(shell, SWT.NONE);
label2.setText("Hello World");
label2.setFont(Display.getCurrent().getSystemFont());

注意:这种方式获取的系统字体font是不需要释放的


图像Image


jface资源管理机制

jface资源管理类:org.eclipse.jface.resource

使用jface资源管理类好处是:只需要使用这些资源,而不用去管释放的问题。当display对象释放的时候,自动释放这些资源。

图像描述符ImageDescriptor

存储图像信息的对象。

创建ImageDescriptor对象

---------------

本地磁盘获取图片资源

ImageDescriptor.createFromFile(SWTApplication.class,"2047488.jpg");

图片要和SWTApplication.java位于同一目录下,才可以正常显示图片

----------------------------

网页URL获取一个图片的资源路径

URL url = null;
try {
	url = new URL("https://rescdn.qqmail.com/bizmail/zh_CN/htmledition/images/bizmail/new_login/exmail_logo_1473e91.png");
} catch (MalformedURLException e) {
	e.printStackTrace();
}
ImageDescriptor.createFromURL(url);

-------------------

image是已经创建的图像对象

Image image=new Image(Display.getCurrent(),"C:\\Users\\lenovo\\Pictures\\2047488.jpg");
ImageDescriptor.createFromImage(image);

在使用createFromImage之前,需要确保image没有被释放掉,否则会抛出异常

------------------------

imageData对象

ImageData data=new ImageData("C:\\Users\\lenovo\\Pictures\\2047488.jpg");
ImageDescriptor.createFromImageData(data);

图像注册器 ImageRegistry

JFace中提供的ImageRegistry类。

使用ImageRegistry类来管理图片的最大好处是,不需要显式地释放存放ImageRegistry对象中的图片资源,当Display对象释放时,会自动释放ImageRegistry对象中存放的图片资源,因为这些都交给了底层的JFace资源管理机制了。

ImageRegistry底层是由一个Map对象管理,通过put方法可以将一个图片对象放入到Map中,通过方法可以将Map中存放的图片对象取出来,通过remove方法可以移除Map中存放的图片对象。

URL url = null;
try {
	url = new URL("https://rescdn.qqmail.com/bizmail/zh_CN/htmledition/images/bizmail/new_login/exmail_logo_1473e91.png");
} catch (MalformedURLException e) {
	e.printStackTrace();
}
Label label = new Label(shell,SWT.NONE);
ImageDescriptor image=ImageDescriptor.createFromURL(url);

//ImageRegistry图片管理。不需要手动释放资源
ImageRegistry ir =	new ImageRegistry();
ir.put("one", image);
label.setImage(ir.get("one"));

整正挺好,把这个图片弄到了哈哈


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值