Skip to main content

Custom TabbedPane drawing

18 replies [Last post]
kawaiimomo
Offline
Joined: 2008-07-10
Points: 0

Hi again,

I want to draw the TabbedPane by myself (rounded tabs, the way the focus is marked, ...). I tried to override the paint(Graphics) method, but this seems to hold only the body of the tabs, because when the focus changes to another tab, the tabs with its names are visibles.

So I guess this is accomplished through LookAndFeel. Probably with getTabbedPaneCell() but I don't get it how it works. Should I extend from DefaultLookAndFeel? And then?

Best regards,
momo

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
chen

Hi,
You can install painters on the SoftButton Style, use
Form.getSoftButtonStyle() to get the Menu Style.
You can also use the PainterChain Painter class to chain a few
painters(the current painter and your own custom one).

Chen

Qunhuan Mei wrote:
> Hi LWUIT team,
>
> I was wondering if there is any way we could customise the display of a Form’s menubar (the screen bottom row), e.g. inserting some strings between left and right softkey names, while keeping menubar’s existing command handling logic.
>
> I could not find any method related to this from those accessible to a Form class.
>
> Thanks,
>
> Qunhuan
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@lwuit.dev.java.net
For additional commands, e-mail: users-help@lwuit.dev.java.net

Qunhuan Mei

Hi Chen,

After receiving You and Shai's reply, I feel the menubar's display is fully under my own control ☺

Many thanks,

Qunhuan

-----Original Message-----
From: Chen.Fishbein@Sun.COM [mailto:Chen.Fishbein@Sun.COM]
Sent: 25 July 2008 14:24
To: users@lwuit.dev.java.net
Subject: Re: Cusomising menubar, feasible (without changing LWUIT's source code)?

Hi,

You can install painters on the SoftButton Style, use

Form.getSoftButtonStyle() to get the Menu Style.

You can also use the PainterChain Painter class to chain a few

painters(the current painter and your own custom one).

Chen

Qunhuan Mei wrote:

> Hi LWUIT team,

>

> I was wondering if there is any way we could customise the display of a Form’s menubar (the screen bottom row), e.g. inserting some strings between left and right softkey names, while keeping menubar’s existing command handling logic.

>

> I could not find any method related to this from those accessible to a Form class.

>

> Thanks,

>

> Qunhuan

>

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

To unsubscribe, e-mail: users-unsubscribe@lwuit.dev.java.net

For additional commands, e-mail: users-help@lwuit.dev.java.net

[att1.html]

Qunhuan Mei

Hi LWUIT team,

I was wondering if there is any way we could customise the display of a Form’s menubar (the screen bottom row), e.g. inserting some strings between left and right softkey names, while keeping menubar’s existing command handling logic.

I could not find any method related to this from those accessible to a Form class.

Thanks,

Qunhuan

Shai Almog

Hi Qunhuan,
currently there is no standard approach for doing that mostly because
the area in the center is "reserved" for the 3rd softbutton
functionality.
I had moderate success in the past with deriving from form and
overriding paint(Graphics) to draw the hour in the center of that
area. This obviously poses some problems in some cases such as the
case where the string of the softbutton is too long.

We might provide something in the future here (suggestions welcome),
but right now the only approach to manipulate the menu bar (beyond
the hack mentioned above) is using a different hack that isn't
guaranteed to work in the future and assumes two softbuttons:
Button b1 = frm.getSoftButton(0);
Button b2 = frm.getSoftButton(1);
Container c = frm.getSoftButton(0).getParent();

c.removeAll();

// place everything into c in the layout you expect and make sure to
restore b1 and b2 to their proper place...

> Hi LWUIT team,
>
> I was wondering if there is any way we could customise the display
> of a Form’s menubar (the screen bottom row), e.g. inserting some
> strings between left and right softkey names, while keeping
> menubar’s existing command handling logic.
>
> I could not find any method related to this from those accessible
> to a Form class.
>
> Thanks,
>
> Qunhuan

Shai Almog
http://lwuit.blogspot.com/

[att1.html]

Qunhuan Mei

Many thanks Shai,

This is very helpful!

Cheers,

Qunhuan

From: Shai.Almog@Sun.COM [mailto:Shai.Almog@Sun.COM]
Sent: 25 July 2008 13:52
To: users@lwuit.dev.java.net
Subject: Re: Cusomising menubar, feasible (without changing LWUIT's source code)?

Hi Qunhuan,
currently there is no standard approach for doing that mostly because the area in the center is "reserved" for the 3rd softbutton functionality.
I had moderate success in the past with deriving from form and overriding paint(Graphics) to draw the hour in the center of that area. This obviously poses some problems in some cases such as the case where the string of the softbutton is too long.

We might provide something in the future here (suggestions welcome), but right now the only approach to manipulate the menu bar (beyond the hack mentioned above) is using a different hack that isn't guaranteed to work in the future and assumes two softbuttons:
Button b1 = frm.getSoftButton(0);
Button b2 = frm.getSoftButton(1);
Container c = frm.getSoftButton(0).getParent();

c.removeAll();

// place everything into c in the layout you expect and make sure to restore b1 and b2 to their proper place...

Hi LWUIT team,

I was wondering if there is any way we could customise the display of a Form's menubar (the screen bottom row), e.g. inserting some strings between left and right softkey names, while keeping menubar's existing command handling logic.

I could not find any method related to this from those accessible to a Form class.

Thanks,

Qunhuan

Shai Almog
http://lwuit.blogspot.com/

[att1.html]

Shai Almog

Hi,

> I want to draw the TabbedPane by myself (rounded tabs, the way the
> focus is marked, ...). I tried to override the paint(Graphics)
> method, but this seems to hold only the body of the tabs, because
> when the focus changes to another tab, the tabs with its names are
> visibles.
>
> So I guess this is accomplished through LookAndFeel. Probably with
> getTabbedPaneCell() but I don't get it how it works. Should I
> extend from DefaultLookAndFeel? And then?

Yes, you can extend the DefaultLookAndFeel and override a specific
method. I do exactly that for my "pimped" series of blog posts at:
http://lwuit.blogspot.com/

Tabbed pane is just a container with a List (actual List component)
attached to it. This method essentially returns the renderer
component (equivalent of the get cell renderer) for the list of tabs.
Notice that this method is not trivial to implement since the line
underneath the tabs is problematic to draw correctly however this
might work for your use case relatively easily.

Just override this method when subclassing default look and feel and
return a component styled for the appropriate selection as if you
were writing a cell renderer.

Thanks.

Shai Almog
http://lwuit.blogspot.com/

[att1.html]

kawaiimomo
Offline
Joined: 2008-07-10
Points: 0

Hi Shai,

thanks as always for your reply. Now the tabs are being drawn by a TabbedPaneCell custom Component.

I started to make this cell renderer as if it was the original that ships with LWUIT (same appearance). The question I have is: Where is stored (if not hardcoded) the bgcolor for a tab when it's not selected? I haven't had success at finding that dark grey color (not bg, not fg, which kind? or it's a Painter?)

Thanks for all your help, keep up the excellent work!

Shai Almog

Hi,
I think you are referring to bgSelectionColor. However we often use
semi transparent colors to fill the background so when there is
selection we define:
cmp.getStyle().setBgTransparency(100);

Thanks.

> Hi Shai,
>
> thanks as always for your reply. Now the tabs are being drawn by a
> TabbedPaneCell custom Component.
>
> I started to make this cell renderer as if it was the original that
> ships with LWUIT (same appearance). The question I have is: Where
> is stored (if not hardcoded) the bgcolor for a tab when it's not
> selected? I haven't had success at finding that dark grey color
> (not bg, not fg, which kind?)
>
> Thanks for all your help, keep up the excellent work!
> [Message sent by forum member 'kawaiimomo' (kawaiimomo)]
>
> http://forums.java.net/jive/thread.jspa?messageID=289044
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@lwuit.dev.java.net
> For additional commands, e-mail: users-help@lwuit.dev.java.net
>

Shai Almog
http://lwuit.blogspot.com/

[att1.html]

kawaiimomo
Offline
Joined: 2008-07-10
Points: 0

Hi Shai,

I think we are not referring to the same thing. I've uploaded a screenshot [url]http://www.4shared.com/file/56398950/465c4ed1/tabscolors.html?[/url] where you can see the first tab selected painted with fgSelectionColor (pink), and white bgColor. The tab that it is not selected has a gray background color, this is the color I want to know where it's defined.

Those are the colors I got through Style: bgColor=FFFFFF, bgSelectionColor=CCFFCC, fgColor=0, fgSelectioncolor=FFCCCC. And the bgTransparency is 0.

Thanks again.

Shai Almog

Hi,
its a hardcoded translucent color:
g.setColor(0);
g.fillRect(getX(), getY(), getWidth(), getHeight
(), (byte) 0x2f);
Thanks.

> Hi Shai,
>
> I think we are not referring to the same thing. I've uploaded a
> screenshot [url]http://www.4shared.com/file/56398950/465c4ed1/
> tabscolors.html?[/url] where you can see the first tab selected
> painted with fgSelectionColor (pink), and white bgColor. The tab
> that it is not selected has a gray background color, this is the
> color I want to know where it's defined.
>
> Those are the colors I got through Style: bgColor=FFFFFF,
> bgSelectionColor=CCFFCC, fgColor=0, fgSelectioncolor=FFCCCC. And
> the bgTransparency is 0.
>
> Thanks again.
> [Message sent by forum member 'kawaiimomo' (kawaiimomo)]
>
> http://forums.java.net/jive/thread.jspa?messageID=289068
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@lwuit.dev.java.net
> For additional commands, e-mail: users-help@lwuit.dev.java.net
>

Shai Almog
http://lwuit.blogspot.com/

[att1.html]

kawaiimomo
Offline
Joined: 2008-07-10
Points: 0

Thanks ;-)

kawaiimomo
Offline
Joined: 2008-07-10
Points: 0

I'm facing a weird issue when painting the last tab (and crashing my head while doing it :-P). The vertical line at right is drawn out of clipping area.

Here's the code:

MIDlet.startApp():
[code]
UIManager.getInstance().setLookAndFeel(new CustomLookAndFeel());
[/code]

MyCustomLookAndFeel:
[code]
import com.sun.lwuit.Component;
import com.sun.lwuit.Image;
import com.sun.lwuit.TabbedPane;
import com.sun.lwuit.geom.Dimension;
import com.sun.lwuit.plaf.DefaultLookAndFeel;
import com.sun.lwuit.plaf.Style;

public class CustomLookAndFeel extends DefaultLookAndFeel {

public Component getTabbedPaneCell(TabbedPane tp, String text, Image icon, boolean isSelected, boolean cellHasFocus, Style cellStyle, Style tabbedPaneStyle, int cellOffsetX, int cellOffsetY, Dimension cellsPreferredSize, Dimension contentPaneSize) {
return TabbedPaneCell.getInstance(tp, text, icon, isSelected, cellHasFocus, cellStyle, tabbedPaneStyle, cellOffsetX, cellOffsetY, cellsPreferredSize, contentPaneSize);
}
}
[/code]

TabbedPaneCell:
[code]
import com.sun.lwuit.Component;
import com.sun.lwuit.Font;
import com.sun.lwuit.Graphics;
import com.sun.lwuit.Image;
import com.sun.lwuit.TabbedPane;
import com.sun.lwuit.geom.Dimension;
import com.sun.lwuit.plaf.Style;

public class TabbedPaneCell extends Component {
private static String text = null;
private static TabbedPane tabbed = null;
private static boolean selected = false;

private static TabbedPaneCell instance = null;

private TabbedPaneCell() {
}

public static TabbedPaneCell getInstance(TabbedPane tp, String txt, Image icon, boolean isSelected, boolean cellHasFocus, Style cellStyle, Style tabbedPaneStyle, int cellOffsetX, int cellOffsetY, Dimension cellsPreferredSize, Dimension contentPaneSize) {
if (instance == null) {
instance = new TabbedPaneCell();
}
text = txt;
tabbed= tp;
selected = isSelected;
return instance;
}

public void paintBorder(Graphics g) {
super.paintBorder(g);
}

public void paintBackground(Graphics g) {
g.setColor(getStyle().getBgColor());
g.fillRect(getX(), getY(), getWidth(), getHeight());
super.paintBackground(g);
}

public Dimension calcPreferredSize() {
return new Dimension(getStyle().getFont().stringWidth(text) + (getStyle().getPadding(LEFT)<<1)/* + (getStyle().getMargin(LEFT)<<1)*/, getStyle().getFont().getHeight() + (getStyle().getPadding(TOP)<<1)/* + (getStyle().getMargin(TOP)<<1)*/);
}

//ONLY TOP Aligmnet supported currently
public void paint(Graphics g) {
//tab
g.setColor(getStyle().getFgColor());
g.drawRect(getX(), getY(), getWidth(), getHeight());

if (selected) {
g.setColor(getStyle().getFgSelectionColor());
g.fillRect(getX()+1, getY()+1, getWidth()-1, getStyle().getMargin(TOP));
}

//text
Font font = getStyle().getFont();
g.setFont(font);

g.drawString(text, getX() + (getWidth()>>1) - (font.stringWidth(text)>>1), getY() + getStyle().getPadding(TOP));
super.paint(g);
}
}
[/code]

And the result:

[url]http://www.4shared.com/file/56404357/8f6cb3d5/moretabs.html?[/url]

Any hint? Advices on this way of implementing custom tab paint?

Thanks a lot!

Shai Almog

> I'm facing a weird issue when painting the last tab (and crashing
> my head while doing it :-P). The vertical line at right is drawn
> out of clipping area.

Try -1 from the width/height. Drawing in Java is a bit "weird" from
the MIDP spec for graphics:

g.fillRect(x, y, w, h); // 1
g.drawRect(x, y, w, h); // 2

Statement (1) fills a rectangle w pixels wide and h pixels high.
Statement (2) draws a rectangle whose left and top edges are within
the area filled by statement (1). However, the bottom and right edges
lie one pixel outside the filled area. This is counterintuitive ...

(there is a "but" there that I snipped out).

Shai Almog
http://lwuit.blogspot.com/

[att1.html]

kawaiimomo
Offline
Joined: 2008-07-10
Points: 0

Hi there,

I know the weird painting behaviour on midp spec. And I already tried to draw rectangle tabs with getWidth()-1, but this leads to have 2 pixels width between tab and tab (end of one, start of next).

By default, the tabs are drawn as they should; why can't I achieve that? I noticed that clipping area is not where it should be placed (to my understanding).

The last pixel you can draw at the rightest side of a tab is not vertical aligned with the pane top line. See this pic: [url]http://www.4shared.com/file/56818869/4fd87483/tabclipping.html?[/url] Painted in black is selected tab, in red the non-selected one. Notice how the right vertical line of selected tab doesn't fit with the panne top line. Any advice on achieving better results?

Thanks.

>
> > I'm facing a weird issue when painting the last tab
> (and crashing
> > my head while doing it :-P). The vertical line at
> right is drawn
> > out of clipping area.
>
> Try -1 from the width/height. Drawing in Java is a
> bit "weird" from
> the MIDP spec for graphics:
>
> g.fillRect(x, y, w, h); // 1
> g.drawRect(x, y, w, h); // 2
>
> Statement (1) fills a rectangle w pixels wide and h
> pixels high.
> Statement (2) draws a rectangle whose left and top
> edges are within
> the area filled by statement (1). However, the bottom
> and right edges
> lie one pixel outside the filled area. This is
> counterintuitive ...
>
> (there is a "but" there that I snipped out).
>
> Shai Almog
> http://lwuit.blogspot.com/
>
> [att1.html]

Shai Almog

Hi kawaiimomo,
the line bellow is drawn by the drawTabbedPaneContentPane method in
the DefaultLookAndFeel. It generally expects the next tab to draw the
left border for the right tab, the reasoning behind this "weirdness"
lies with some of the many edge cases you get with a tabbed pane
control.
You can either override drawTabbedPaneContentPane() for your needs or
draw the line in the next cell (except for the special case of the
last cell).

Thanks.

> Hi there,
>
> I know the weird painting behaviour on midp spec. And I already
> tried to draw rectangle tabs with getWidth()-1, but this leads to
> have 2 pixels width between tab and tab (end of one, start of next).
>
> By default, the tabs are drawn as they should; why can't I achieve
> that? I noticed that clipping area is not where it should be placed
> (to my understanding).
>
> The last pixel you can draw at the rightest side of a tab is not
> vertical aligned with the pane top line. See this pic: [url]http://
> www.4shared.com/file/56818869/4fd87483/tabclipping.html?[/url]
> Painted in black is selected tab, in red the non-selected one.
> Notice how the right vertical line of selected tab doesn't fit with
> the panne top line. Any advice on achieving better results?
>
> Thanks.
>
> http://forums.java.net/jive/thread.jspa?messageID=289735
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@lwuit.dev.java.net
> For additional commands, e-mail: users-help@lwuit.dev.java.net
>

Shai Almog
http://lwuit.blogspot.com/

[att1.html]

kawaiimomo
Offline
Joined: 2008-07-10
Points: 0

Hi Shai,

thanks a lot for your response, I'll try overriding drawTabbedPaneContentPane() :-)

kawaiimomo
Offline
Joined: 2008-07-10
Points: 0

Hi again,

I thought I better start with each cell drawing the edge of the previous one.

Just a question, how can I identify if the cell I'm drawing is the last one? Using
drawTabbedPaneContentPane is easy because you have a param with the tab number.
So how can I know the cell number when calling getTabbedPaneCell and drawing with
that Cell renderer??

kawaiimomo
Offline
Joined: 2008-07-10
Points: 0

Well, I don't think this is a nice approach, but I identify the currently drawing cell with this:
[code]
(int)(((float)getX() / (float)cellsDim.getWidth()) * tabbed.getTabCount())
[/code]