JDK-6354790 : GTK LAF: Painting bugs in JTabbedPane
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,linux_2.6
  • CPU: generic,x86
  • Submitted: 2005-11-23
  • Updated: 2011-03-09
  • Resolved: 2011-03-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b10Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
In GTK LAF, there are several painting defects in tabbed panes:

1. Tabs are too high.
2. There should be no horizontal line under the selected tab. At least in Simple, Clearlooks, several other themes.
3. When the first tab is selected it is not left aligned with tabbed pane.

All the descriptions above are for TOP tab placement.

Comments
SUGGESTED FIX http://javaweb.sfbay/jcg/1.7.0-dolphin/swing/6354790/
16-01-2007

EVALUATION To address problem 1, i've tried the insets code above but it actually makes things worse: tabs become 3 pixels shorter than they should (now they're 1 pixel higher). So i left vertical insets in their current state. Hovewer, horizontal insets will be fixed as suggested. Problem 2: we pass NULL as clip to gtk_paint_box_gap(). Clearlooks engine relies on clipping to draw the gap, so there should be real clip rect instead. Problem 3 has already been fixed under #6416920. The box gap issue will be fixed under bug 5089821, please see Evaluation there. GTKLookAndFeel also redefines the property "TabbedPane.selectionFollowsFocus" to be false. It should be true in GTK as well as all other LAFs.
12-01-2007

EVALUATION One more thing we noticed the other day related to tabs... In GTKLookAndFeel.getDefaults() we have: // SynthTabbedPaneUI supports rollover on tabs, GTK does not table.put("TabbedPane.isTabRollover", Boolean.TRUE); The code contradicts the comment; I think that should be FALSE instead of TRUE. We probably didn't notice this earlier because there's no difference in rendering in the native layer, but we should probably fix it anyway.
03-11-2006

EVALUATION There are two other (vaguely worded) bug reports that seem to be related to this one; see 5004995 and 5089821. We may be able to close those as duplicates of this one if we're able to fix all the problems here. I did some investigation of the first issue (tabs too tall). Well, tab width is also a concern here. There are a couple issues contributing to the incorrect width/height of tabs. First, in SynthTabbedPaneUI.calculateTabWidth() we have this mysterious line: int width = tabInsets.left + tabInsets.right + 3; Where does that magic number 3 come from? I dunno, but that's basically responsible for making all tabs 3 pixels wider than they need to be. I suggest that we remove that "+ 3", after all it should be up to the SynthStyle to include extra padding in the insets if necessary. The second issue is the way that we calculate the insets for tabs in GTKStyle.getTabbedPaneTabInsets(). Currently we use pretty much the same inset values for all sides of the tab, regardless of the tab placement policy (top/bottom/left/right). Native GtkNotebook code uses different padding for the vertical portions than the horiztontal portions, which explains why Swing's tabs look much taller than native. We need to copy the native behavior. I'll paste the necessary modifications here so that we don't lose them (I don't have time right now to complete the full fix for this bug report): private Insets getTabbedPaneTabInsets(SynthContext context, Insets insets) { // The following calculations are derived from gtknotebook.c // (GTK+ version 2.8.20), gtk_notebook_size_request() method. int xThickness = getXThickness(); int yThickness = getYThickness(); int focusSize = getClassSpecificIntValue(context, "focus-line-width",1); int TAB_OVERLAP = 2; int TAB_CURVATURE = 1; int TAB_BORDER = 2; // default value of "tab-h/vborder" property int pad = TAB_CURVATURE + focusSize + TAB_BORDER - (TAB_OVERLAP / 2); // REMIND: GTKStyleFactory will cache one GTKStyle for JTabbedPanes // regardless of the tab placement; we need to find a way to ensure // we return a different GTKStyle for each possible tab placement JTabbedPane tabbedPane = (JTabbedPane)context.getComponent(); switch (tabbedPane.getTabPlacement()) { case SwingConstants.TOP: case SwingConstants.BOTTOM: default: insets.left = insets.right = pad + xThickness; insets.top = insets.bottom = focusSize + yThickness; break; case SwingConstants.LEFT: case SwingConstants.RIGHT: insets.left = insets.right = focusSize + xThickness; insets.top = insets.bottom = pad + yThickness; break; } return insets; } With these two fixes, Swing's tabs are sized much closer to native ones, although we're still not identical. The tab height seems to be identical, but the tab width is one pixel shorter than native, and the text/focus bounding box is offset differently than native. I haven't been able to figure that out yet. Also, there are differences in the way that we render tab overlap for non-selected tabs when compared to native, which needs to be investigated. I also investigated one other issue related to tabs, specifically the way we incorrectly render the "box gap" in GTKPainter.paintTabbedPaneContentBackground(). Currently we sometimes will see a couple pixel artifacts in this border on the left side when the first tab is selected. I think this is probably related to the way we specify the "gapStart" parameter in that method. Currently we have (for TOP/BOTTOM): gapStart = tabBounds.x - 1; If I change that to: gapStart = tabBounds.x - 2; then we are identical to native tabs (at least this seems to work for the few themes I tested: Clearlooks, Ubuntulooks, Simple, Nimbus). But the question remains: why "2"? I'll leave that to the RE to figure out :)
03-11-2006