`
weimou66
  • 浏览: 1278021 次
文章分类
社区版块
存档分类
最新评论

如何编写多页标签页 Tab Control组件,附全部代码

 
阅读更多

OS 5.0的黑莓平台没有提供多页标签栏,下面我们来实现一个。

效果如下图,三个栏目,选择不同的栏目(TabItem),下面的内容不同(Manager)。

标签页是用一个定制的Field TabItem,在paint()方法中根据该Field是focus与否的状态选择显示不同的背景图片。

标签页被选中的时候,调用fieldChangeNotify( 0 )方法通知TabControl窗口需要更换标签页下面的manager显示不同的内容。

代码中用到的三个资源文件:

tabitem_default.png ,注意图片的右边,是有个凹陷的效果

tabitem_selected.png,和上面的图片是相同大小,但是颜色是白色的,右边有个竖线

table_background.png,这张图片将被铺满整条横向的Tab栏目。

详细代码如下:

TabControl.java

TabItem.java

BaseButtonField.java

package cn.rim.samples.tabcontrol;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.decor.Background;
import net.rim.device.api.ui.decor.BackgroundFactory;

public class TabControl extends Manager {

public TabControl() {
super(0);
Background bitmapBackground = BackgroundFactory.createBitmapBackground(Bitmap.getBitmapResource("table_background.png"));
setBackground(bitmapBackground);
}


public int getPreferredWidth() {
return Display.getWidth();
}

public int getPreferredHeight() {
if (getFieldCount()>0)
return getField(0).getPreferredHeight();
else
return 5;
}

protected void sublayout(int width, int height) {
int x = 0;
int y = 0;
Field field;
int numberOfFields = getFieldCount();
for (int i=0; i<numberOfFields; ++i) {
field = getField(i);
setPositionChild(field, x, y);
layoutChild(field, width, height);

x += field.getPreferredWidth();
}
setExtent(getPreferredWidth(), getPreferredHeight());
}

protected boolean navigationMovement ( int dx, int dy, int status, int time ) {

int focusIndex = getFieldWithFocusIndex();
int columns = getFieldCount();
if (dx > 0 ) { //向右滚动
if ( focusIndex < columns-1 ) {
getField(focusIndex+1).setFocus();
return true;
}else {
getField(0).setFocus();
return true;
}
}
if (dx < 0) {//向左滚动
if ( focusIndex ==0 ) {
getField(columns-1).setFocus();
return true;
}else {
getField(focusIndex-1).setFocus();
return true;
}
}

//向上向下的滚动这里就不做处理了
return false;
}
}

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

package cn.rim.samples.tabcontrol;

import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;

public class TabItem extends BaseButtonField
{
private Bitmap[] _bitmaps;
private static final int NORMAL = 0;
private static final int FOCUS = 1;

private String text;//标签栏文字
/*
public BitmapButtonField( Bitmap normalState )
{
this( normalState, normalState, 0 );
}
*/
public TabItem( Bitmap normalState, Bitmap focusState )
{
this( normalState, focusState, 0 );
}

public TabItem( Bitmap normalState, Bitmap focusState, long style )
{
super( Field.FOCUSABLE | style );

if( (normalState.getWidth() != focusState.getWidth())
|| (normalState.getHeight() != focusState.getHeight()) ){

throw new IllegalArgumentException( "Image sizes don't match" );
}

_bitmaps = new Bitmap[] { normalState, focusState };
}

//Yang Jiang
public void setText(String value) {
this.text = value;
}

public void setImage( Bitmap normalState ){
_bitmaps[NORMAL] = normalState;
invalidate();
}

public void setFocusImage( Bitmap focusState ){
_bitmaps[FOCUS] = focusState;
invalidate();
}

public int getPreferredWidth() {
return _bitmaps[NORMAL].getWidth();
}

public int getPreferredHeight() {
return _bitmaps[NORMAL].getHeight();
}

protected void layout( int width, int height ) {
setExtent( _bitmaps[NORMAL].getWidth(), _bitmaps[NORMAL].getHeight() );
}

protected void paint( Graphics g ) {
int index = g.isDrawingStyleSet( Graphics.DRAWSTYLE_FOCUS ) ? FOCUS : NORMAL;
g.drawBitmap( 0, 0, _bitmaps[index].getWidth(), _bitmaps[index].getHeight(), _bitmaps[index], 0, 0 );
g.drawText(text, 0, this.getHeight()/2,
Graphics.VCENTER | Graphics.HCENTER, this.getWidth());
}

/**
* With this commented out the default focus will show through
* If an app doesn't want focus colours then it should override this and do nothing
**/
/*
protected void paintBackground( Graphics g ) {
// Nothing to do here
}
*/

protected void drawFocus( Graphics g, boolean on ) {
// Paint() handles it all
g.setDrawingStyle( Graphics.DRAWSTYLE_FOCUS, true );
paintBackground( g );
paint( g );
}
}

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

package cn.rim.samples.tabcontrol;

import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;


/**
* Implements all the stuff we don't want to do each time we need a new button
*/
public abstract class BaseButtonField extends Field
{
private XYRect _drawFocusTempRect = new XYRect();

public BaseButtonField()
{
this( 0 );
}

public BaseButtonField( long style )
{
super( Field.FOCUSABLE | style );
}

protected void layout( int width, int height )
{
setExtent( 10, 10 );
}

protected void drawFocus( Graphics g, boolean on )
{
getFocusRect( _drawFocusTempRect );

boolean oldDrawStyleFocus = g.isDrawingStyleSet( Graphics.DRAWSTYLE_FOCUS );
boolean notEmpty = g.pushContext( _drawFocusTempRect.x, _drawFocusTempRect.y, _drawFocusTempRect.width, _drawFocusTempRect.height, 0, 0 );

try {
if( notEmpty ) {
g.setDrawingStyle( Graphics.DRAWSTYLE_FOCUS, on );
paintBackground( g );
paint( g );
}
} finally {
g.popContext();
g.setDrawingStyle( Graphics.DRAWSTYLE_FOCUS, oldDrawStyleFocus );
}
}

protected boolean keyChar( char character, int status, int time )
{
if( character == Characters.ENTER ) {
clickButton();
return true;
}
return super.keyChar( character, status, time );
}

protected boolean navigationClick( int status, int time )
{
clickButton();
return true;
}

protected boolean trackwheelClick( int status, int time )
{
clickButton();
return true;
}

protected boolean invokeAction( int action )
{
switch( action ) {
case ACTION_INVOKE: {
clickButton();
return true;
}
}
return super.invokeAction( action );
}

public void setDirty( boolean dirty ) {
// We never want to be dirty or muddy
}

public void setMuddy( boolean muddy ) {
// We never want to be dirty or muddy
}

/**
* A public way to click this button
*/
public void clickButton()
{
fieldChangeNotify( 0 );
}
}

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

package cn.rim.samples.tabcontrol;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FocusChangeListener;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.ui.decor.Background;
import net.rim.device.api.ui.decor.BackgroundFactory;

public class DemoApp extends UiApplication {

public DemoApp() {
TabControlScreen screen = new TabControlScreen();
pushScreen(screen);
}

/**
* @param args
*/
public static void main(String[] args) {
DemoApp app = new DemoApp();
app.enterEventDispatcher();
}

private class TabControlScreen extends MainScreen implements FocusChangeListener {

private TabItem tab1;
private TabItem tab2;
private TabItem tab3;

private Manager tabArea;

private Manager tab1Manager;
private Manager tab2Manager;
private Manager tab3Manager;

public TabControlScreen() {
TabControl tabcontrol = new TabControl();

tab1 = new TabItem(Bitmap.getBitmapResource("tabitem_default.png"), Bitmap.getBitmapResource("tabitem_selected.png"));
tab1.setText("Page 1");
tab2 = new TabItem(Bitmap.getBitmapResource("tabitem_default.png"), Bitmap.getBitmapResource("tabitem_selected.png"));
tab2.setText("Page 2");
tab3 = new TabItem(Bitmap.getBitmapResource("tabitem_default.png"), Bitmap.getBitmapResource("tabitem_selected.png"));
tab3.setText("Page 3");

tab1.setFocusListener(this);
tab2.setFocusListener(this);
tab3.setFocusListener(this);
tabcontrol.add(tab1);
tabcontrol.add(tab2);
tabcontrol.add(tab3);

add(tabcontrol);
add(new SeparatorField());

tabArea = displayTab1();
add(tabArea);
}

public void focusChanged(Field field, int eventType) {
if (tabArea != null) {
if (eventType == FOCUS_GAINED) {
if (field == tab1) {
System.out.println("Switch to Tab 1");
delete(tabArea);
tabArea = displayTab1();
add(tabArea);
} else if (field == tab2) {
System.out.println("Switch to Tab 2");
System.out.println("Switch to Tab 1");
delete(tabArea);
tabArea = displayTab2();
add(tabArea);
} else if (field == tab3) {
System.out.println("Switch to Tab 3");
System.out.println("Switch to Tab 1");
delete(tabArea);
tabArea = displayTab3();
add(tabArea);
}
}
}

}

public Manager displayTab1() {
if (tab1Manager == null) {
tab1Manager = new VerticalFieldManager();
tab1Manager.add(new LabelField ("Tab 1 content here."));
tab1Manager.add(new LabelField ("Tab 1 content here again."));
}
return tab1Manager;
}

public Manager displayTab2() {
if (tab2Manager == null) {
tab2Manager = new VerticalFieldManager();
tab2Manager.add(new LabelField ("Tab 2 content here."));
tab2Manager.add(new LabelField ("Tab 2 content here again."));
}
return tab2Manager;
}

public Manager displayTab3() {
if (tab3Manager == null) {
tab3Manager = new VerticalFieldManager();
tab3Manager.add(new LabelField ("Tab 3 content here."));
tab3Manager.add(new LabelField ("Tab 3 content here again."));
}
return tab3Manager;
}
}
}
--------------------------------------------------------------------------------------------------------

分享到:
评论

相关推荐

    mfc tab control 标签切换 页面改变

    "mfc tab control 标签切换 页面改变"这个主题涉及了如何在MFC应用中实现和处理TabControl的标签切换事件,并在不同页面之间动态更新显示的数据。 首先,我们需要理解MFC中的TabControl是如何工作的。TabControl...

    MFC TAB control

    在MFC中,Tab Control是一种常用控件,它允许用户通过标签页的形式组织和切换不同的视图或内容。在这个名为"TabControl"的程序中,我们将探讨如何在Visual Studio 2010环境下使用MFC实现Tab Control。 1. **创建MFC...

    一个基于ASP.NET的增强设计时定义的A Web Tab Control 标签控件源码

    在给定的标题和描述中,我们关注的是一个特定的控件——"A Web Tab Control",这是一款针对ASP.NET平台设计的标签控件,用于在网页上实现类似浏览器标签页的功能。 标签控件(Tab Control)在Web开发中非常常见,它...

    VC2008 MFC Tab Control控件的应用

    在Microsoft Visual C++ 2008(MFC)中,Tab Control控件是一个非常实用的组件,它允许用户在一个窗口中组织多个视图或者对话框,就像浏览器中的标签页一样,方便用户在不同功能间快速切换。这个"VC2008 MFC Tab ...

    use tab control

    Tab Control允许用户通过点击不同的标签页在多个视图或内容之间切换,这种设计使得复杂的软件界面更加有组织且易于导航。下面我们将深入探讨Tab Control的使用、功能、设计原则以及常见实现技术。 1. **Tab Control...

    对话框上的TAB标签的使用,给每个TAB页装上一个对话框

    在对话框中,我们有时会看到TAB标签(Tab Control),它允许用户通过点击不同的标签在多个相关的页面之间切换,每个标签页通常包含一组相关控件或内容。这种设计模式极大地提高了用户体验,因为它组织了复杂的信息并...

    tab control code

    在Windows编程中,"tab control" 是一个常用组件,它允许用户通过标签页来组织和切换不同的内容区域。本文将详细解析"tab control code"的相关知识点,并基于提供的文件名进行解释。 1. **控件介绍**: Tab ...

    MFC Tab控件添加图片及选定后标题变色

    在Windows应用程序开发中,Microsoft Foundation Class (MFC)库提供了一种方便的方式来创建用户界面,其中Tab控件是一个常用组件,用于实现类似书签或标签页的效果。本教程将详细介绍如何在MFC中为Tab控件添加图片...

    mfc中使用tab control的另一种方法

    通过这种方式,我们可以在同一个对话框中轻松管理多个标签页,而无需创建和管理多个子对话框,从而简化代码结构,提高程序效率。 在提供的压缩包文件中,`MyTab.sln`是一个Visual Studio解决方案文件,包含整个项目...

    A Web Tab Control Enhanced With Design Time Support

    Web Tab控件是Web应用程序开发中常见的组件,用于在单一界面中组织多个页面或内容区域,提供类似桌面应用的多标签体验。设计时支持则意味着开发者在编写代码前可以在设计环境中预览和配置控件,从而提高开发效率和...

    C++中MFC Tab Control控件的使用详解

    MFC Tab Control控件是MFC库中的一个组件,它允许用户通过标签页的形式展示多个界面或功能区域,从而提高用户界面的组织性和易用性。下面我们将详细介绍如何在C++中使用MFC Tab Control控件。 首先,创建一个新的...

    仿IE7.0窗口中多文档的标签Tab控制

    在C#编程环境中,开发一款具有类似IE7.0浏览器窗口功能的应用程序,其中的关键技术是实现多文档界面(MDI)以及标签页控件。本文将深入探讨如何利用C#来创建这样的用户界面,主要关注两个核心部分:MDI容器和自定义...

    Delphi 动态创建 tab 控件

    Tab 控件(TTabControl 或 WC_TABCONTROL - SysTabControl32)是 Windows 用户界面中一种常用组件,它允许用户通过点击不同的标签来切换显示不同的内容区域。在 Delphi 中,我们可以直接使用 VCL(Visual Component ...

    ASP.NET网页Tab选项卡控件源码及示例

    内容索引:.NET源码,控件组件,选项卡,控件 一个用C#编写的用于网页的TAB选项卡控件源代码,并附有一个使用示例,包括在静态环境下的一个HTML示例,TAB选项卡如图示,效果很不错,部分功能使用了JQUERY配合,这使得...

    DrawTabCtrl.rar

    在Windows编程中,`Tab Control` 是一个非常常见的组件,用于在不同的页面间切换,常用于设置界面或者多选项卡的界面布局。本资源“DrawTabCtrl.rar”提供了一个自定义的`Tab Control`控件类,使得开发者可以更加...

    TabSheet_tabsheet源文件_Tabú_TabSheet_fierce7og_MFCTabcontrol_

    总的来说,`Tabsheet.cpp`和`Tabsheet.h`这两个文件构成了一个自定义的Tab Control实现,它们结合了MFC的`CTabCtrl`类,为MFC应用程序提供了用户友好的多页界面。通过阅读和理解这两个文件,开发者可以学习到如何在...

    java实现的Tab选项

    Java 实现的Tab选项是一种常见的用户界面(UI)设计元素,用于在有限的空间内组织和切换多个视图或内容面板。在Java编程中,我们可以利用Java Swing或JavaFX库来创建这样的功能。以下是对这个主题的详细阐述: 一、...

    MFC中Tab控件的使用方法

    在MFC框架下,`Tab Control`(标签控件)是一种常见的UI组件,用于实现多页式的界面布局,类似于浏览器的标签页功能,可以方便地切换不同的视图或数据集。本文将详细介绍如何在MFC应用程序中集成并使用`Tab Control`...

    非常好的一个tab选项卡

    【标题】:“非常好的一个tab选项卡”指的是在Web开发中常用的一种用户界面元素,它允许在单个容器内切换多个视图或内容区域。在VS2005(Visual Studio 2005)这个集成开发环境中,通过JavaScript实现的tab选项卡...

    C#重绘TabControl的Tabpage标签,添加图片及关闭按钮

    在C#编程中,TabControl控件是Windows Forms应用程序中常用的一种组件,用于展示多个相关的页面或窗体。本文将详细讲解如何通过重绘TabControl来实现Tabpage标签的自定义,包括添加图片和关闭按钮。 首先,为了实现...

Global site tag (gtag.js) - Google Analytics