J2ME Tabbed Menu

We will build a reusable Tabbed Menu using J2ME.

Image:J2me_tabbed_menu.jpg

You can find a midlet showing this component in action here.

Our component will support:

  • Full styling of tabs (bg color, fore color, font face, margin, paddings and corner radius)
  • Automatic horizontal scrolling, so that you can put as many tab you want, without caring about screen width

Let's start from the customizable variables, whose aim is self-explaining:

int background = 0xffffff;
int bgColor = 0xcccccc;
int bgFocusedColor = 0x0000ff;
int foreColor = 0x000000;
int foreFocusedColor = 0xffffff;
int cornerRadius = 4;
int padding = 2;
int margin = 2;
Font font = Font.getDefaultFont();
int scrollStep = 20;

Then we'll define some internal variables, used to mantain the tabbed menu state:

int selectedTab = 0;	//selected tab index
int[] tabsWidth = null; //width of single tabs
int[] tabsLeft = null; //left X coordinate of single tabs
int tabHeight = 0; //height of tabs (equal for all tabs)
String[] tabs = null; //tab labels
int menuWidth = 0; //total menu width
 
int viewportWidth = 0; //visible viewport width
int viewportX = 0; //current viewport X coordinate

Now, we'll define a simple constructor accepting tab labels and viewport width as parameters:

public TabMenu(String[] tabs, int width)
{
this.tabs = tabs;

this.viewportWidth = width;

initialize();
}
void initialize()
{
tabHeight = font.getHeight() + cornerRadius + 2 * padding;

menuWidth = 0;

tabsWidth = new int[tabs.length];
tabsLeft = new int[tabs.length];

for(int i = 0; i < tabsWidth.length; i++)
{
tabsWidth[i] = font.stringWidth(tabs[i]) + 2 * padding + 2 * cornerRadius;

tabsLeft[i] = menuWidth;

menuWidth += tabsWidth[i];

if(i > 0)
{
menuWidth += margin;
}
}
}

Now, let's define an utility method to check if a tab is visible or not.

private boolean isTabVisible(int tabIndex)
{
return tabsLeft[tabIndex] < viewportX + viewportWidth &&
tabsLeft[tabIndex] + tabsWidth[tabIndex] >= viewportX;
}

And now we'll implement the tab switching/scrolling methods, that will use the isTabVisible method defined above:

public void goRight()
{
go(+1);
}
public void goLeft()
{
go(-1);
}
private void go(int delta)
{
int newTab = Math.max(0, Math.min(tabs.length - 1, selectedTab + delta));

boolean scroll = true;

if(newTab != selectedTab && isTabVisible(newTab))
{
selectedTab = newTab;

if( (delta > 0 && tabsLeft[selectedTab] + tabsWidth[selectedTab] > viewportX + viewportWidth) ||
(delta < 0 && tabsLeft[selectedTab] < viewportX))
{
scroll = true;
}
else
{
scroll = false;
}
}
if(scroll)
{
viewportX = Math.max(0, Math.min(menuWidth - viewportWidth, viewportX + delta * scrollStep));
}
}

And now, we're ready to paint our menu :)

public void paint(Graphics g)
{
int currentX = - viewportX;

g.setClip(0, 0, viewportWidth, tabHeight);

g.setColor(background);
g.fillRect(0, 0, viewportWidth, tabHeight);

for(int i = 0; i < tabs.length; i++)
{
g.setColor(i == selectedTab ? bgFocusedColor : bgColor);

g.fillRoundRect(currentX, 0, tabsWidth[i], tabHeight + cornerRadius, 2 * cornerRadius, 2 * cornerRadius);

g.setColor(i == selectedTab ? foreFocusedColor : foreColor);

g.drawString(tabs[i], currentX + cornerRadius + padding, cornerRadius + padding, Graphics.LEFT | Graphics.TOP);

currentX += tabsWidth[i] + margin;
}
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值