/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Provides the Synth L&F UI delegate for
* {@link javax.swing.JTabbedPane}.
*
* <p>Looks up the {@code selectedTabPadInsets} property from the Style,
* which represents additional insets for the selected tab.
*
* @author Scott Violet
* @since 1.7
*/
implements PropertyChangeListener, SynthUI {
/**
* <p>If non-zero, tabOverlap indicates the amount that the tab bounds
* should be altered such that they would overlap with a tab on either the
* leading or trailing end of a run (ie: in TOP, this would be on the left
* or right).</p>
*
* <p>When tabOverlap is specified, it both changes the x position and width
* of the tab if in TOP or BOTTOM placement, and changes the y position and
* height if in LEFT or RIGHT placement.</p>
*
* <p>This is done for the following reason. Consider a run of 10 tabs.
* There are 9 gaps between these tabs. If you specified a tabOverlap of
* "-1", then each of the tabs "x" values will be shifted left. This leaves
* 9 pixels of space to the right of the right-most tab unpainted. So, each
* tab's width is also extended by 1 pixel to make up the difference.</p>
*
* <p>This property respects the RTL component orientation.</p>
*/
/**
* When a tabbed pane has multiple rows of tabs, this indicates whether
* the tabs in the upper row(s) should extend to the base of the tab area,
* or whether they should remain at their normal tab height. This does not
* affect the bounds of the tabs, only the bounds of area painted by the
* tabs. The text position does not change. The result is that the bottom
* border of the upper row of tabs becomes fully obscured by the lower tabs,
* resulting in a cleaner look.
*/
private boolean extendTabsToBase = false;
//added for the Nimbus look and feel, where the tab area is painted differently depending on the
//state for the selected tab
private boolean tabAreaStatesMatchSelectedTab = false;
//added for the Nimbus LAF to ensure that the labels don't move whether the tab is selected or not
private boolean nudgeSelectedLabel = true;
private boolean selectedTabIsPressed = false;
/**
* Creates a new UI object for the given component.
*
* @param c component to create UI object for
* @return the UI object
*/
return new SynthTabbedPaneUI();
}
private boolean scrollableTabLayoutEnabled() {
}
/**
* @inheritDoc
*/
protected void installDefaults() {
}
// Add properties other than JComponent colors, Borders and
// opacity settings here:
"TabbedPane.extendTabsToBase", false);
"TabbedPane.selectedTabPadInsets");
if (selectedTabPadInsets == null) {
}
"TabbedPane.tabAreaStatesMatchSelectedTab", false);
"TabbedPane.nudgeSelectedLabel", true);
}
}
if (tabContext != null) {
}
if (tabAreaContext != null) {
}
if (tabContentContext != null) {
}
this);
}
/**
* @inheritDoc
*/
protected void installListeners() {
super.installListeners();
tabPane.addPropertyChangeListener(this);
}
/**
* @inheritDoc
*/
protected void uninstallListeners() {
super.uninstallListeners();
}
/**
* @inheritDoc
*/
protected void uninstallDefaults() {
tabContext = null;
tabAreaStyle = null;
}
/**
* @inheritDoc
*/
}
}
}
}
}
}
/**
* @inheritDoc
*/
// added for Nimbus LAF so that it can use the basic arrow buttons
// UIManager is queried directly here because this is called before
// updateStyle is called so the style can not be queried directly
return btn;
}
return new SynthScrollableTabButton(direction);
}
/**
* @inheritDoc
*/
if (SynthLookAndFeel.shouldUpdateStyle(e)) {
}
}
/**
* @inheritDoc
*
* Overridden to keep track of whether the selected tab is also pressed.
*/
return new MouseListener() {
public void mousePressed(MouseEvent e) {
return;
}
// Clicking on selected tab
selectedTabIsPressed = true;
//TODO need to just repaint the tab area!
}
}
//forward the event (this will set the selected index, or none at all
delegate.mousePressed(e);
}
public void mouseReleased(MouseEvent e) {
if (selectedTabIsPressed) {
selectedTabIsPressed = false;
//TODO need to just repaint the tab area!
}
//forward the event
//hack: The super method *should* be setting the mouse-over property correctly
//here, but it doesn't. That is, when the mouse is released, whatever tab is below the
//released mouse should be in rollover state. But, if you select a tab and don't
//move the mouse, this doesn't happen. Hence, forwarding the event.
delegate2.mouseMoved(e);
}
};
}
/**
* @inheritDoc
*/
if (nudgeSelectedLabel) {
} else {
return 0;
}
}
/**
* @inheritDoc
*/
if (nudgeSelectedLabel) {
} else {
return 0;
}
}
/**
* Notifies this UI delegate to repaint the specified component.
* This method paints the component background, then calls
* the {@link #paint(SynthContext,Graphics)} method.
*
* <p>In general, this method does not need to be overridden by subclasses.
* All Look and Feel rendering code should reside in the {@code paint} method.
*
* @param g the {@code Graphics} object used for painting
* @param c the component being painted
* @see #paint(SynthContext,Graphics)
*/
}
/**
* @inheritDoc
*/
return super.getBaseline(tab);
}
}
/**
* @inheritDoc
*/
int y, int w, int h) {
}
/**
* Paints the specified component according to the Look and Feel.
* <p>This method is not used by Synth Look and Feel.
* Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
*
* @param g the {@code Graphics} object used for painting
* @param c the component being painted
* @see #paint(SynthContext,Graphics)
*/
}
/**
* Paints the specified component.
*
* @param context context for the component being painted
* @param g the {@code Graphics} object used for painting
* @see #update(Graphics,JComponent)
*/
// Paint tab area
// If scrollable tabs are enabled, the tab area will be
// painted by the scrollable tab panel instead.
//
if (!scrollableTabLayoutEnabled()) { // WRAP_TAB_LAYOUT
int size;
switch(tabPlacement) {
case LEFT:
break;
case RIGHT:
break;
case BOTTOM:
break;
case TOP:
default:
}
}
}
// Paint content border
}
int selectedIndex) {
// This can be invoked from ScrollabeTabPanel
}
int tabPlacement, int selectedIndex,
//if the tab area's states should match that of the selected tab, then
//first update the selected tab's states, then set the state
//for the tab area to match
//otherwise, restore the tab area's state to ENABLED (which is the
//only supported state otherwise).
(getRolloverTab() == selectedIndex),
(getFocusIndex() == selectedIndex));
} else {
}
// Paint the tab area.
// Paint tabRuns of tabs from back to front
textRect);
}
}
}
if (selectedIndex >= 0) {
}
}
}
/**
* @inheritDoc
*/
int oldRolloverTab = getRolloverTab();
super.setRolloverTab(index);
//TODO need to just repaint the tab area!
} else {
if (r != null) {
}
}
if (index >= 0) {
if (r != null) {
}
}
}
}
(getRolloverTab() == tabIndex),
(getFocusIndex() == tabIndex));
int x = tabRect.x;
int y = tabRect.y;
//paint this tab such that its edge closest to the base is equal to
//edge of the selected tab closest to the base. In terms of the TOP
//tab placement, this will cause the bottom of each tab to be
//painted even with the bottom of the selected tab. This is because
//in each tab placement (TOP, LEFT, BOTTOM, RIGHT) the selected tab
//is closest to the base.
if (selectedIndex >= 0) {
switch (placement) {
case TOP:
break;
case LEFT:
break;
case BOTTOM:
int topY = r.y;
y = topY;
break;
case RIGHT:
int leftX = r.x;
x = leftX;
break;
}
}
}
}
}
if (v != null) {
}
}
Graphics g, int tabPlacement,
boolean isSelected) {
if (v != null) {
// html
} else {
// plain text
}
}
int tabPlacement, int selectedIndex) {
switch(tabPlacement) {
case LEFT:
break;
case RIGHT:
break;
case BOTTOM:
break;
case TOP:
default:
}
w, h);
}
private void ensureCurrentLayout() {
}
/* If tabPane doesn't have a peer yet, the validate() call will
* silently fail. We handle that by forcing a layout if tabPane
* is still invalid. See bug 4237677.
*/
}
}
/**
* @inheritDoc
*/
tabContext));
int result = 0;
for(int i = 0; i < tabCount; i++) {
}
return result;
}
/**
* @inheritDoc
*/
if (tabComponent != null) {
} else {
}
if (v != null) {
// html
} else {
// plain text
}
}
return width;
}
/**
* @inheritDoc
*/
tabContext));
int result = 0;
for(int i = 0; i < tabCount; i++) {
result);
}
return result;
}
/**
* @inheritDoc
*/
updateTabContext(tabIndex, false, false, false,
(getFocusIndex() == tabIndex));
return tabInsets;
}
/**
* @inheritDoc
*/
}
}
int state = 0;
if (selected) {
}
}
else if (selected) {
}
}
else if (isMouseOver) {
}
else {
}
}
if (isMouseDown) {
}
}
/**
* @inheritDoc
*
* Overridden to create a TabbedPaneLayout subclass which takes into
* account tabOverlap.
*/
return super.createLayoutManager();
} else { /* WRAP_TAB_LAYOUT */
return new TabbedPaneLayout() {
public void calculateLayoutInfo() {
super.calculateLayoutInfo();
//shift all the tabs, if necessary
if (tabOverlap != 0) {
//left-to-right/right-to-left only affects layout
//when placement is TOP or BOTTOM
// xshift and yshift represent the amount &
// direction to shift the tab in their
// respective axis.
int xshift = 0;
int yshift = 0;
// configure xshift and y shift based on tab
switch (tabPane.getTabPlacement()) {
case JTabbedPane.TOP:
case JTabbedPane.BOTTOM:
break;
case JTabbedPane.LEFT:
case JTabbedPane.RIGHT:
yshift = tabOverlap;
break;
default: //do nothing
}
}
}
}
}
};
}
}
super(direction);
setName("TabbedPane.button");
}
}
}