mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-13 07:17:13 -06:00
@@ -5,6 +5,9 @@ FlatLaf Change Log
|
|||||||
|
|
||||||
#### New features and improvements
|
#### New features and improvements
|
||||||
|
|
||||||
|
- TabbedPane: Support scrolling tabs with mouse wheel (if `tabLayoutPolicy` is
|
||||||
|
`SCROLL_TAB_LAYOUT`). (issue #40)
|
||||||
|
- TabbedPane: Repeat scrolling as long as arrow buttons are pressed. (issue #40)
|
||||||
- Support painting separator line between window title and content (use UI value
|
- Support painting separator line between window title and content (use UI value
|
||||||
`TitlePane.borderColor`). (issue #184)
|
`TitlePane.borderColor`). (issue #184)
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,14 @@ public interface FlatSystemProperties
|
|||||||
*/
|
*/
|
||||||
String MENUBAR_EMBEDDED = "flatlaf.menuBarEmbedded";
|
String MENUBAR_EMBEDDED = "flatlaf.menuBarEmbedded";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether animations are enabled.
|
||||||
|
* <p>
|
||||||
|
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||||
|
* <strong>Default</strong> {@code true}
|
||||||
|
*/
|
||||||
|
String ANIMATION = "flatlaf.animation";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether vertical text position is corrected when UI is scaled on HiDPI screens.
|
* Specifies whether vertical text position is corrected when UI is scaled on HiDPI screens.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -20,17 +20,22 @@ import static com.formdev.flatlaf.util.UIScale.scale;
|
|||||||
import static com.formdev.flatlaf.FlatClientProperties.*;
|
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.KeyboardFocusManager;
|
import java.awt.KeyboardFocusManager;
|
||||||
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.event.InputEvent;
|
import java.awt.event.InputEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
@@ -40,13 +45,18 @@ import java.util.Set;
|
|||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JTabbedPane;
|
import javax.swing.JTabbedPane;
|
||||||
|
import javax.swing.JViewport;
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.Timer;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
||||||
import javax.swing.text.View;
|
import javax.swing.text.View;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
|
import com.formdev.flatlaf.util.Animator;
|
||||||
|
import com.formdev.flatlaf.util.CubicBezierEasing;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,6 +100,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault TabbedPane.showTabSeparators boolean
|
* @uiDefault TabbedPane.showTabSeparators boolean
|
||||||
* @uiDefault TabbedPane.tabSeparatorsFullHeight boolean
|
* @uiDefault TabbedPane.tabSeparatorsFullHeight boolean
|
||||||
* @uiDefault TabbedPane.hasFullBorder boolean
|
* @uiDefault TabbedPane.hasFullBorder boolean
|
||||||
|
* @uiDefault ScrollPane.smoothScrolling boolean
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -117,6 +128,12 @@ public class FlatTabbedPaneUI
|
|||||||
protected boolean hasFullBorder;
|
protected boolean hasFullBorder;
|
||||||
protected boolean tabsOverlapBorder;
|
protected boolean tabsOverlapBorder;
|
||||||
|
|
||||||
|
protected JViewport tabViewport;
|
||||||
|
protected FlatWheelTabScroller wheelTabScroller;
|
||||||
|
|
||||||
|
private Handler handler;
|
||||||
|
private boolean blockRollover;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return new FlatTabbedPaneUI();
|
return new FlatTabbedPaneUI();
|
||||||
}
|
}
|
||||||
@@ -188,36 +205,87 @@ public class FlatTabbedPaneUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PropertyChangeListener createPropertyChangeListener() {
|
protected void installComponents() {
|
||||||
return new BasicTabbedPaneUI.PropertyChangeHandler() {
|
super.installComponents();
|
||||||
@Override
|
|
||||||
public void propertyChange( PropertyChangeEvent e ) {
|
|
||||||
super.propertyChange( e );
|
|
||||||
|
|
||||||
switch( e.getPropertyName() ) {
|
// find scrollable tab viewport
|
||||||
case TABBED_PANE_SHOW_TAB_SEPARATORS:
|
tabViewport = null;
|
||||||
case TABBED_PANE_SHOW_CONTENT_SEPARATOR:
|
if( isScrollTabLayout() ) {
|
||||||
case TABBED_PANE_HAS_FULL_BORDER:
|
for( Component c : tabPane.getComponents() ) {
|
||||||
case TABBED_PANE_TAB_HEIGHT:
|
if( c instanceof JViewport && c.getClass().getName().equals( "javax.swing.plaf.basic.BasicTabbedPaneUI$ScrollableTabViewport" ) ) {
|
||||||
tabPane.revalidate();
|
tabViewport = (JViewport) c;
|
||||||
tabPane.repaint();
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void installListeners() {
|
||||||
|
super.installListeners();
|
||||||
|
|
||||||
|
tabPane.addMouseListener( getHandler() );
|
||||||
|
|
||||||
|
if( tabViewport != null && (wheelTabScroller = createWheelTabScroller()) != null ) {
|
||||||
|
// ideally we would add the mouse listeners to the viewport, but then the
|
||||||
|
// mouse listener of the tabbed pane would not receive events while
|
||||||
|
// the mouse pointer is over the viewport
|
||||||
|
tabPane.addMouseWheelListener( wheelTabScroller );
|
||||||
|
tabPane.addMouseMotionListener( wheelTabScroller );
|
||||||
|
tabPane.addMouseListener( wheelTabScroller );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void uninstallListeners() {
|
||||||
|
super.uninstallListeners();
|
||||||
|
|
||||||
|
if( handler != null ) {
|
||||||
|
tabPane.removeMouseListener( handler );
|
||||||
|
handler = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( wheelTabScroller != null ) {
|
||||||
|
wheelTabScroller.uninstall();
|
||||||
|
|
||||||
|
tabPane.removeMouseWheelListener( wheelTabScroller );
|
||||||
|
tabPane.removeMouseMotionListener( wheelTabScroller );
|
||||||
|
tabPane.removeMouseListener( wheelTabScroller );
|
||||||
|
wheelTabScroller = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Handler getHandler() {
|
||||||
|
if( handler == null )
|
||||||
|
handler = new Handler();
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected FlatWheelTabScroller createWheelTabScroller() {
|
||||||
|
return new FlatWheelTabScroller();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PropertyChangeListener createPropertyChangeListener() {
|
||||||
|
Handler handler = getHandler();
|
||||||
|
handler.propertyChangeDelegate = super.createPropertyChangeListener();
|
||||||
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected JButton createScrollButton( int direction ) {
|
protected JButton createScrollButton( int direction ) {
|
||||||
// this method is invoked before installDefaults(), so we can not use color fields here
|
return new FlatScrollableTabButton( direction );
|
||||||
return new FlatArrowButton( direction, UIManager.getString( "Component.arrowType" ),
|
}
|
||||||
UIManager.getColor( "TabbedPane.foreground" ),
|
|
||||||
UIManager.getColor( "TabbedPane.disabledForeground" ), null,
|
protected void setRolloverTab( int x, int y ) {
|
||||||
UIManager.getColor( "TabbedPane.hoverColor" ) );
|
setRolloverTab( tabForCoordinate( tabPane, x, y ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setRolloverTab( int index ) {
|
protected void setRolloverTab( int index ) {
|
||||||
|
if( blockRollover )
|
||||||
|
return;
|
||||||
|
|
||||||
int oldIndex = getRolloverTab();
|
int oldIndex = getRolloverTab();
|
||||||
super.setRolloverTab( index );
|
super.setRolloverTab( index );
|
||||||
|
|
||||||
@@ -489,17 +557,13 @@ public class FlatTabbedPaneUI
|
|||||||
|
|
||||||
// repaint selection in scroll-tab-layout because it may be painted before
|
// repaint selection in scroll-tab-layout because it may be painted before
|
||||||
// the content border was painted (from BasicTabbedPaneUI$ScrollableTabPanel)
|
// the content border was painted (from BasicTabbedPaneUI$ScrollableTabPanel)
|
||||||
if( isScrollTabLayout() && selectedIndex >= 0 ) {
|
if( isScrollTabLayout() && selectedIndex >= 0 && tabViewport != null ) {
|
||||||
Component scrollableTabViewport = findComponentByClassName( tabPane,
|
Rectangle tabRect = getTabBounds( tabPane, selectedIndex );
|
||||||
BasicTabbedPaneUI.class.getName() + "$ScrollableTabViewport" );
|
|
||||||
if( scrollableTabViewport != null ) {
|
|
||||||
Rectangle tabRect = getTabBounds( tabPane, selectedIndex );
|
|
||||||
|
|
||||||
Shape oldClip = g.getClip();
|
Shape oldClip = g.getClip();
|
||||||
g.setClip( scrollableTabViewport.getBounds() );
|
g.setClip( tabViewport.getBounds() );
|
||||||
paintTabSelection( g, tabPlacement, tabRect.x, tabRect.y, tabRect.width, tabRect.height );
|
paintTabSelection( g, tabPlacement, tabRect.x, tabRect.y, tabRect.width, tabRect.height );
|
||||||
g.setClip( oldClip );
|
g.setClip( oldClip );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,17 +582,332 @@ public class FlatTabbedPaneUI
|
|||||||
return tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT;
|
return tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Component findComponentByClassName( Container c, String className ) {
|
protected boolean isSmoothScrollingEnabled() {
|
||||||
for( Component child : c.getComponents() ) {
|
if( !Animator.useAnimation() )
|
||||||
if( className.equals( child.getClass().getName() ) )
|
return false;
|
||||||
return child;
|
|
||||||
|
|
||||||
if( child instanceof Container ) {
|
// Note: Getting UI value "ScrollPane.smoothScrolling" here to allow
|
||||||
Component c2 = findComponentByClassName( (Container) child, className );
|
// applications to turn smooth scrolling on or off at any time
|
||||||
if( c2 != null )
|
// (e.g. in application options dialog).
|
||||||
return c2;
|
return UIManager.getBoolean( "ScrollPane.smoothScrolling" );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class FlatScrollableTabButton --------------------------------------
|
||||||
|
|
||||||
|
protected class FlatScrollableTabButton
|
||||||
|
extends FlatArrowButton
|
||||||
|
implements MouseListener
|
||||||
|
{
|
||||||
|
private Timer autoRepeatTimer;
|
||||||
|
|
||||||
|
protected FlatScrollableTabButton( int direction ) {
|
||||||
|
// this method is invoked before installDefaults(), so we can not use color fields here
|
||||||
|
super( direction, UIManager.getString( "Component.arrowType" ),
|
||||||
|
UIManager.getColor( "TabbedPane.foreground" ),
|
||||||
|
UIManager.getColor( "TabbedPane.disabledForeground" ), null,
|
||||||
|
UIManager.getColor( "TabbedPane.hoverColor" ) );
|
||||||
|
|
||||||
|
addMouseListener( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getPreferredSize() {
|
||||||
|
Dimension size = super.getPreferredSize();
|
||||||
|
if( direction == WEST || direction == EAST )
|
||||||
|
return new Dimension( size.width, Math.max( size.height, maxTabHeight ) );
|
||||||
|
else
|
||||||
|
return new Dimension( Math.max( size.width, maxTabWidth ), size.height );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed( MouseEvent e ) {
|
||||||
|
if( SwingUtilities.isLeftMouseButton( e ) && isEnabled() ) {
|
||||||
|
if( autoRepeatTimer == null ) {
|
||||||
|
// using same delays as in BasicScrollBarUI and BasicSpinnerUI
|
||||||
|
autoRepeatTimer = new Timer( 60, e2 -> {
|
||||||
|
if( isEnabled() )
|
||||||
|
doClick();
|
||||||
|
} );
|
||||||
|
autoRepeatTimer.setInitialDelay( 300 );
|
||||||
|
}
|
||||||
|
|
||||||
|
autoRepeatTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased( MouseEvent e ) {
|
||||||
|
if( autoRepeatTimer != null )
|
||||||
|
autoRepeatTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked( MouseEvent e ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered( MouseEvent e ) {
|
||||||
|
if( autoRepeatTimer != null && isPressed() )
|
||||||
|
autoRepeatTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited( MouseEvent e ) {
|
||||||
|
if( autoRepeatTimer != null )
|
||||||
|
autoRepeatTimer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class FlatWheelTabScroller -----------------------------------------
|
||||||
|
|
||||||
|
protected class FlatWheelTabScroller
|
||||||
|
extends MouseAdapter
|
||||||
|
{
|
||||||
|
private int lastMouseX;
|
||||||
|
private int lastMouseY;
|
||||||
|
|
||||||
|
private boolean inViewport;
|
||||||
|
private boolean scrolled;
|
||||||
|
private Timer rolloverTimer;
|
||||||
|
private Timer exitedTimer;
|
||||||
|
|
||||||
|
private Animator animator;
|
||||||
|
private Point startViewPosition;
|
||||||
|
private Point targetViewPosition;
|
||||||
|
|
||||||
|
protected void uninstall() {
|
||||||
|
if( rolloverTimer != null )
|
||||||
|
rolloverTimer.stop();
|
||||||
|
if( exitedTimer != null )
|
||||||
|
exitedTimer.stop();
|
||||||
|
if( animator != null )
|
||||||
|
animator.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved( MouseWheelEvent e ) {
|
||||||
|
// because this listener receives mouse events for the whole tabbed pane,
|
||||||
|
// we have to check whether the mouse is located over the viewport
|
||||||
|
if( !isInViewport( e.getX(), e.getY() ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
lastMouseX = e.getX();
|
||||||
|
lastMouseY = e.getY();
|
||||||
|
|
||||||
|
double preciseWheelRotation = e.getPreciseWheelRotation();
|
||||||
|
|
||||||
|
// compute new view position
|
||||||
|
Point viewPosition = (targetViewPosition != null)
|
||||||
|
? targetViewPosition
|
||||||
|
: tabViewport.getViewPosition();
|
||||||
|
Dimension viewSize = tabViewport.getViewSize();
|
||||||
|
int x = viewPosition.x;
|
||||||
|
int y = viewPosition.y;
|
||||||
|
int tabPlacement = tabPane.getTabPlacement();
|
||||||
|
if( tabPlacement == TOP || tabPlacement == BOTTOM ) {
|
||||||
|
x += maxTabHeight * preciseWheelRotation;
|
||||||
|
x = Math.min( Math.max( x, 0 ), viewSize.width - tabViewport.getWidth() );
|
||||||
|
} else {
|
||||||
|
y += maxTabHeight * preciseWheelRotation;
|
||||||
|
y = Math.min( Math.max( y, 0 ), viewSize.height - tabViewport.getHeight() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whether view position has changed
|
||||||
|
Point newViewPosition = new Point( x, y );
|
||||||
|
if( newViewPosition.equals( viewPosition ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// update view position
|
||||||
|
if( preciseWheelRotation != 0 &&
|
||||||
|
preciseWheelRotation != e.getWheelRotation() )
|
||||||
|
{
|
||||||
|
// do not use animation for precise scrolling (e.g. with trackpad)
|
||||||
|
|
||||||
|
// stop running animation (if any)
|
||||||
|
if( animator != null )
|
||||||
|
animator.stop();
|
||||||
|
|
||||||
|
tabViewport.setViewPosition( newViewPosition );
|
||||||
|
updateRolloverDelayed();
|
||||||
|
} else
|
||||||
|
setViewPositionAnimated( newViewPosition );
|
||||||
|
|
||||||
|
scrolled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setViewPositionAnimated( Point viewPosition ) {
|
||||||
|
// check whether position is equal to current position
|
||||||
|
if( viewPosition.equals( tabViewport.getViewPosition() ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// do not use animation if disabled
|
||||||
|
if( !isSmoothScrollingEnabled() ) {
|
||||||
|
tabViewport.setViewPosition( viewPosition );
|
||||||
|
updateRolloverDelayed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remember start and target view positions
|
||||||
|
startViewPosition = tabViewport.getViewPosition();
|
||||||
|
targetViewPosition = viewPosition;
|
||||||
|
|
||||||
|
// create animator
|
||||||
|
if( animator == null ) {
|
||||||
|
// using same delays as in FlatScrollBarUI
|
||||||
|
int duration = 200;
|
||||||
|
int resolution = 10;
|
||||||
|
|
||||||
|
animator = new Animator( duration, fraction -> {
|
||||||
|
if( tabViewport == null || !tabViewport.isShowing() ) {
|
||||||
|
animator.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update view position
|
||||||
|
int x = startViewPosition.x + Math.round( (targetViewPosition.x - startViewPosition.x) * fraction );
|
||||||
|
int y = startViewPosition.y + Math.round( (targetViewPosition.y - startViewPosition.y) * fraction );
|
||||||
|
tabViewport.setViewPosition( new Point( x, y ) );
|
||||||
|
}, () -> {
|
||||||
|
startViewPosition = targetViewPosition = null;
|
||||||
|
|
||||||
|
if( tabPane != null )
|
||||||
|
setRolloverTab( lastMouseX, lastMouseY );
|
||||||
|
} );
|
||||||
|
|
||||||
|
animator.setResolution( resolution );
|
||||||
|
animator.setInterpolator( new CubicBezierEasing( 0.5f, 0.5f, 0.5f, 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// restart animator
|
||||||
|
animator.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateRolloverDelayed() {
|
||||||
|
blockRollover = true;
|
||||||
|
|
||||||
|
// keep rollover on last tab until it would move to another tab, then clear it
|
||||||
|
int oldIndex = getRolloverTab();
|
||||||
|
if( oldIndex >= 0 ) {
|
||||||
|
int index = tabForCoordinate( tabPane, lastMouseX, lastMouseY );
|
||||||
|
if( index >= 0 && index != oldIndex ) {
|
||||||
|
// clear if moved to another tab
|
||||||
|
blockRollover = false;
|
||||||
|
setRolloverTab( -1 );
|
||||||
|
blockRollover = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create timer
|
||||||
|
if( rolloverTimer == null ) {
|
||||||
|
rolloverTimer = new Timer( 150, e -> {
|
||||||
|
blockRollover = false;
|
||||||
|
|
||||||
|
// highlight tab at mouse location
|
||||||
|
if( tabPane != null )
|
||||||
|
setRolloverTab( lastMouseX, lastMouseY );
|
||||||
|
} );
|
||||||
|
rolloverTimer.setRepeats( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
// restart timer
|
||||||
|
rolloverTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved( MouseEvent e ) {
|
||||||
|
checkViewportExited( e.getX(), e.getY() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited( MouseEvent e ) {
|
||||||
|
// this event occurs also if mouse is moved to a custom tab component
|
||||||
|
// that handles mouse events (e.g. a close button)
|
||||||
|
checkViewportExited( e.getX(), e.getY() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed( MouseEvent e ) {
|
||||||
|
// for the case that the tab was only partly visible before the user clicked it
|
||||||
|
setRolloverTab( e.getX(), e.getY() );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isInViewport( int x, int y ) {
|
||||||
|
return (tabViewport != null && tabViewport.getBounds().contains( x, y ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkViewportExited( int x, int y ) {
|
||||||
|
lastMouseX = x;
|
||||||
|
lastMouseY = y;
|
||||||
|
|
||||||
|
boolean wasInViewport = inViewport;
|
||||||
|
inViewport = isInViewport( x, y );
|
||||||
|
|
||||||
|
if( inViewport != wasInViewport ) {
|
||||||
|
if( !inViewport )
|
||||||
|
viewportExited();
|
||||||
|
else if( exitedTimer != null )
|
||||||
|
exitedTimer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void viewportExited() {
|
||||||
|
if( !scrolled )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( exitedTimer == null ) {
|
||||||
|
exitedTimer = new Timer( 500, e -> ensureSelectedTabVisible() );
|
||||||
|
exitedTimer.setRepeats( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
exitedTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void ensureSelectedTabVisible() {
|
||||||
|
// check whether UI delegate was uninstalled because this method is invoked via timer
|
||||||
|
if( tabPane == null || tabViewport == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( !scrolled || tabViewport == null )
|
||||||
|
return;
|
||||||
|
scrolled = false;
|
||||||
|
|
||||||
|
int selectedIndex = tabPane.getSelectedIndex();
|
||||||
|
if( selectedIndex >= 0 ) {
|
||||||
|
Rectangle tabBounds = getTabBounds( tabPane, selectedIndex );
|
||||||
|
tabViewport.scrollRectToVisible( tabBounds );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class Handler ------------------------------------------------------
|
||||||
|
|
||||||
|
private class Handler
|
||||||
|
extends MouseAdapter
|
||||||
|
implements PropertyChangeListener
|
||||||
|
{
|
||||||
|
PropertyChangeListener propertyChangeDelegate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited( MouseEvent e ) {
|
||||||
|
// this event occurs also if mouse is moved to a custom tab component
|
||||||
|
// that handles mouse events (e.g. a close button)
|
||||||
|
// --> make sure that the tab stays highlighted
|
||||||
|
setRolloverTab( e.getX(), e.getY() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
propertyChangeDelegate.propertyChange( e );
|
||||||
|
|
||||||
|
switch( e.getPropertyName() ) {
|
||||||
|
case TABBED_PANE_SHOW_TAB_SEPARATORS:
|
||||||
|
case TABBED_PANE_SHOW_CONTENT_SEPARATOR:
|
||||||
|
case TABBED_PANE_HAS_FULL_BORDER:
|
||||||
|
case TABBED_PANE_TAB_HEIGHT:
|
||||||
|
tabPane.revalidate();
|
||||||
|
tabPane.repaint();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.formdev.flatlaf.util;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import javax.swing.Timer;
|
import javax.swing.Timer;
|
||||||
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple animator based on ideas and concepts from "Filthy Rich Clients" book
|
* Simple animator based on ideas and concepts from "Filthy Rich Clients" book
|
||||||
@@ -39,6 +40,15 @@ public class Animator
|
|||||||
private long startTime;
|
private long startTime;
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether animations are enabled (the default) or disabled via
|
||||||
|
* system property {@code flatlaf.animation} set to {@code false}.
|
||||||
|
* This allows disabling all animations at command line with {@code -Dflatlaf.animation=false}.
|
||||||
|
*/
|
||||||
|
public static boolean useAnimation() {
|
||||||
|
return FlatSystemProperties.getBoolean( FlatSystemProperties.ANIMATION, true );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an animation that runs duration milliseconds.
|
* Creates an animation that runs duration milliseconds.
|
||||||
* Use {@link #addTarget(TimingTarget)} to receive timing events
|
* Use {@link #addTarget(TimingTarget)} to receive timing events
|
||||||
@@ -174,14 +184,17 @@ public class Animator
|
|||||||
timeToStop = false;
|
timeToStop = false;
|
||||||
startTime = System.nanoTime() / 1000000;
|
startTime = System.nanoTime() / 1000000;
|
||||||
|
|
||||||
timer = new Timer( resolution, e -> {
|
if( timer == null ) {
|
||||||
if( !hasBegun ) {
|
timer = new Timer( resolution, e -> {
|
||||||
begin();
|
if( !hasBegun ) {
|
||||||
hasBegun = true;
|
begin();
|
||||||
}
|
hasBegun = true;
|
||||||
|
}
|
||||||
|
|
||||||
timingEvent( getTimingFraction() );
|
timingEvent( getTimingFraction() );
|
||||||
} );
|
} );
|
||||||
|
} else
|
||||||
|
timer.setDelay( resolution );
|
||||||
timer.setInitialDelay( 0 );
|
timer.setInitialDelay( 0 );
|
||||||
timer.start();
|
timer.start();
|
||||||
}
|
}
|
||||||
@@ -203,10 +216,11 @@ public class Animator
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void stop( boolean cancel ) {
|
private void stop( boolean cancel ) {
|
||||||
if( timer != null ) {
|
if( !running )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( timer != null )
|
||||||
timer.stop();
|
timer.stop();
|
||||||
timer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !cancel )
|
if( !cancel )
|
||||||
end();
|
end();
|
||||||
@@ -215,6 +229,15 @@ public class Animator
|
|||||||
timeToStop = false;
|
timeToStop = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restarts the animation.
|
||||||
|
* Invokes {@link #cancel()} and {@link #start()}.
|
||||||
|
*/
|
||||||
|
public void restart() {
|
||||||
|
cancel();
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this animation is running.
|
* Returns whether this animation is running.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_SHOW_TAB_SEPA
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.*;
|
import javax.swing.border.*;
|
||||||
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
|
import com.formdev.flatlaf.icons.FlatInternalFrameCloseIcon;
|
||||||
import com.formdev.flatlaf.util.ScaledImageIcon;
|
import com.formdev.flatlaf.util.ScaledImageIcon;
|
||||||
import com.jgoodies.forms.layout.*;
|
import com.jgoodies.forms.layout.*;
|
||||||
import net.miginfocom.swing.*;
|
import net.miginfocom.swing.*;
|
||||||
@@ -32,6 +34,9 @@ import net.miginfocom.swing.*;
|
|||||||
public class FlatContainerTest
|
public class FlatContainerTest
|
||||||
extends FlatTestPanel
|
extends FlatTestPanel
|
||||||
{
|
{
|
||||||
|
private final int initialTabCount;
|
||||||
|
private boolean autoMoreTabs;
|
||||||
|
|
||||||
public static void main( String[] args ) {
|
public static void main( String[] args ) {
|
||||||
SwingUtilities.invokeLater( () -> {
|
SwingUtilities.invokeLater( () -> {
|
||||||
FlatTestFrame frame = FlatTestFrame.create( args, "FlatContainerTest" );
|
FlatTestFrame frame = FlatTestFrame.create( args, "FlatContainerTest" );
|
||||||
@@ -43,6 +48,10 @@ public class FlatContainerTest
|
|||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
addInitialTabs( tabbedPane1, tabbedPane2, tabbedPane3, tabbedPane4 );
|
addInitialTabs( tabbedPane1, tabbedPane2, tabbedPane3, tabbedPane4 );
|
||||||
|
initialTabCount = tabbedPane1.getTabCount();
|
||||||
|
|
||||||
|
tabScrollCheckBox.setSelected( true );
|
||||||
|
tabScrollChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tabScrollChanged() {
|
private void tabScrollChanged() {
|
||||||
@@ -63,8 +72,6 @@ public class FlatContainerTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean autoMoreTabs;
|
|
||||||
|
|
||||||
private void showTabSeparatorsChanged() {
|
private void showTabSeparatorsChanged() {
|
||||||
Boolean showTabSeparators = showTabSeparatorsCheckBox.isSelected() ? true : null;
|
Boolean showTabSeparators = showTabSeparatorsCheckBox.isSelected() ? true : null;
|
||||||
putTabbedPanesClientProperty( TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators );
|
putTabbedPanesClientProperty( TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators );
|
||||||
@@ -88,28 +95,30 @@ public class FlatContainerTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void moreTabsChanged() {
|
private void moreTabsChanged() {
|
||||||
boolean moreTabs = moreTabsCheckBox.isSelected();
|
moreTabsSpinnerChanged();
|
||||||
addRemoveMoreTabs( tabbedPane1, moreTabs );
|
|
||||||
addRemoveMoreTabs( tabbedPane2, moreTabs );
|
|
||||||
addRemoveMoreTabs( tabbedPane3, moreTabs );
|
|
||||||
addRemoveMoreTabs( tabbedPane4, moreTabs );
|
|
||||||
|
|
||||||
autoMoreTabs = false;
|
autoMoreTabs = false;
|
||||||
|
|
||||||
|
moreTabsSpinner.setEnabled( moreTabsCheckBox.isSelected() );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addRemoveMoreTabs( JTabbedPane tabbedPane, boolean add ) {
|
private void moreTabsSpinnerChanged() {
|
||||||
if( add ) {
|
addRemoveMoreTabs( tabbedPane1 );
|
||||||
addTab( tabbedPane, "Tab 4", "tab content 4" );
|
addRemoveMoreTabs( tabbedPane2 );
|
||||||
addTab( tabbedPane, "Tab 5", "tab content 5" );
|
addRemoveMoreTabs( tabbedPane3 );
|
||||||
addTab( tabbedPane, "Tab 6", "tab content 6" );
|
addRemoveMoreTabs( tabbedPane4 );
|
||||||
addTab( tabbedPane, "Tab 7", "tab content 7" );
|
}
|
||||||
addTab( tabbedPane, "Tab 8", "tab content 8" );
|
|
||||||
} else {
|
private void addRemoveMoreTabs( JTabbedPane tabbedPane ) {
|
||||||
int tabCount = tabbedPane.getTabCount();
|
int oldTabCount = tabbedPane.getTabCount();
|
||||||
if( tabCount > 4 ) {
|
int newTabCount = initialTabCount + (moreTabsCheckBox.isSelected() ? (Integer) moreTabsSpinner.getValue() : 0);
|
||||||
for( int i = 0; i < 5; i++ )
|
|
||||||
tabbedPane.removeTabAt( tabbedPane.getTabCount() - 1 );
|
if( newTabCount > oldTabCount ) {
|
||||||
}
|
for( int i = oldTabCount + 1; i <= newTabCount; i++ )
|
||||||
|
addTab( tabbedPane, "Tab " + i, "tab content " + i );
|
||||||
|
} else if( newTabCount < oldTabCount ) {
|
||||||
|
while( tabbedPane.getTabCount() > 4 )
|
||||||
|
tabbedPane.removeTabAt( tabbedPane.getTabCount() - 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +171,50 @@ public class FlatContainerTest
|
|||||||
tabbedPane.setIconAt( 1, icon );
|
tabbedPane.setIconAt( 1, icon );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void customBorderChanged() {
|
||||||
|
Border border = customBorderCheckBox.isSelected()
|
||||||
|
? new LineBorder( Color.magenta, 20 )
|
||||||
|
: null;
|
||||||
|
|
||||||
|
tabbedPane1.setBorder( border );
|
||||||
|
tabbedPane2.setBorder( border );
|
||||||
|
tabbedPane3.setBorder( border );
|
||||||
|
tabbedPane4.setBorder( border );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void customTabsChanged() {
|
||||||
|
customTabsChanged( tabbedPane1 );
|
||||||
|
customTabsChanged( tabbedPane2 );
|
||||||
|
customTabsChanged( tabbedPane3 );
|
||||||
|
customTabsChanged( tabbedPane4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void customTabsChanged( JTabbedPane tabbedPane ) {
|
||||||
|
if( customTabsCheckBox.isSelected() ) {
|
||||||
|
tabbedPane.setTabComponentAt( 1, new JButton( tabbedPane1.getTitleAt( 1 ) ) );
|
||||||
|
tabbedPane.setTabComponentAt( 3, createCustomTab( tabbedPane1.getTitleAt( 3 ) ) );
|
||||||
|
} else {
|
||||||
|
tabbedPane.setTabComponentAt( 1, null );
|
||||||
|
tabbedPane.setTabComponentAt( 3, null );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Component createCustomTab( String tabTitle ) {
|
||||||
|
JButton closeButton;
|
||||||
|
if( UIManager.getLookAndFeel() instanceof FlatLaf ) {
|
||||||
|
closeButton = new JButton( new FlatInternalFrameCloseIcon() );
|
||||||
|
closeButton.setContentAreaFilled( false );
|
||||||
|
closeButton.setBorder( null );
|
||||||
|
} else
|
||||||
|
closeButton = new JButton( "x" );
|
||||||
|
|
||||||
|
JPanel tab = new JPanel( new BorderLayout( 5, 0 ) );
|
||||||
|
tab.setOpaque( false );
|
||||||
|
tab.add( closeButton, BorderLayout.EAST );
|
||||||
|
tab.add( new JLabel( tabTitle ), BorderLayout.CENTER );
|
||||||
|
return tab;
|
||||||
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
JPanel panel9 = new JPanel();
|
JPanel panel9 = new JPanel();
|
||||||
@@ -182,12 +235,15 @@ public class FlatContainerTest
|
|||||||
tabbedPane4 = new JTabbedPane();
|
tabbedPane4 = new JTabbedPane();
|
||||||
JPanel panel14 = new JPanel();
|
JPanel panel14 = new JPanel();
|
||||||
moreTabsCheckBox = new JCheckBox();
|
moreTabsCheckBox = new JCheckBox();
|
||||||
|
moreTabsSpinner = new JSpinner();
|
||||||
tabScrollCheckBox = new JCheckBox();
|
tabScrollCheckBox = new JCheckBox();
|
||||||
showTabSeparatorsCheckBox = new JCheckBox();
|
showTabSeparatorsCheckBox = new JCheckBox();
|
||||||
hideContentSeparatorCheckBox = new JCheckBox();
|
hideContentSeparatorCheckBox = new JCheckBox();
|
||||||
hasFullBorderCheckBox = new JCheckBox();
|
|
||||||
tabIconsCheckBox = new JCheckBox();
|
tabIconsCheckBox = new JCheckBox();
|
||||||
tabIconSizeSpinner = new JSpinner();
|
tabIconSizeSpinner = new JSpinner();
|
||||||
|
customBorderCheckBox = new JCheckBox();
|
||||||
|
customTabsCheckBox = new JCheckBox();
|
||||||
|
hasFullBorderCheckBox = new JCheckBox();
|
||||||
CellConstraints cc = new CellConstraints();
|
CellConstraints cc = new CellConstraints();
|
||||||
|
|
||||||
//======== this ========
|
//======== this ========
|
||||||
@@ -294,14 +350,13 @@ public class FlatContainerTest
|
|||||||
"insets 0,hidemode 3",
|
"insets 0,hidemode 3",
|
||||||
// columns
|
// columns
|
||||||
"[]" +
|
"[]" +
|
||||||
"[]" +
|
|
||||||
"[]" +
|
|
||||||
"[fill]" +
|
"[fill]" +
|
||||||
"[]" +
|
"[]" +
|
||||||
"[fill]" +
|
"[]" +
|
||||||
"[fill]",
|
"[fill]",
|
||||||
// rows
|
// rows
|
||||||
"[center]"));
|
"[center]" +
|
||||||
|
"[]"));
|
||||||
|
|
||||||
//---- moreTabsCheckBox ----
|
//---- moreTabsCheckBox ----
|
||||||
moreTabsCheckBox.setText("More tabs");
|
moreTabsCheckBox.setText("More tabs");
|
||||||
@@ -309,37 +364,53 @@ public class FlatContainerTest
|
|||||||
moreTabsCheckBox.addActionListener(e -> moreTabsChanged());
|
moreTabsCheckBox.addActionListener(e -> moreTabsChanged());
|
||||||
panel14.add(moreTabsCheckBox, "cell 0 0");
|
panel14.add(moreTabsCheckBox, "cell 0 0");
|
||||||
|
|
||||||
|
//---- moreTabsSpinner ----
|
||||||
|
moreTabsSpinner.setModel(new SpinnerNumberModel(4, 0, null, 1));
|
||||||
|
moreTabsSpinner.setEnabled(false);
|
||||||
|
moreTabsSpinner.addChangeListener(e -> moreTabsSpinnerChanged());
|
||||||
|
panel14.add(moreTabsSpinner, "cell 1 0");
|
||||||
|
|
||||||
//---- tabScrollCheckBox ----
|
//---- tabScrollCheckBox ----
|
||||||
tabScrollCheckBox.setText("Use scroll layout");
|
tabScrollCheckBox.setText("Use scroll layout");
|
||||||
tabScrollCheckBox.setMnemonic('S');
|
tabScrollCheckBox.setMnemonic('S');
|
||||||
tabScrollCheckBox.addActionListener(e -> tabScrollChanged());
|
tabScrollCheckBox.addActionListener(e -> tabScrollChanged());
|
||||||
panel14.add(tabScrollCheckBox, "cell 1 0,alignx left,growx 0");
|
panel14.add(tabScrollCheckBox, "cell 2 0,alignx left,growx 0");
|
||||||
|
|
||||||
//---- showTabSeparatorsCheckBox ----
|
//---- showTabSeparatorsCheckBox ----
|
||||||
showTabSeparatorsCheckBox.setText("Show tab separators");
|
showTabSeparatorsCheckBox.setText("Show tab separators");
|
||||||
showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
|
showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
|
||||||
panel14.add(showTabSeparatorsCheckBox, "cell 2 0");
|
panel14.add(showTabSeparatorsCheckBox, "cell 3 0");
|
||||||
|
|
||||||
//---- hideContentSeparatorCheckBox ----
|
//---- hideContentSeparatorCheckBox ----
|
||||||
hideContentSeparatorCheckBox.setText("Hide content separator");
|
hideContentSeparatorCheckBox.setText("Hide content separator");
|
||||||
hideContentSeparatorCheckBox.addActionListener(e -> hideContentSeparatorChanged());
|
hideContentSeparatorCheckBox.addActionListener(e -> hideContentSeparatorChanged());
|
||||||
panel14.add(hideContentSeparatorCheckBox, "cell 3 0");
|
panel14.add(hideContentSeparatorCheckBox, "cell 4 0");
|
||||||
|
|
||||||
//---- hasFullBorderCheckBox ----
|
|
||||||
hasFullBorderCheckBox.setText("Show content border");
|
|
||||||
hasFullBorderCheckBox.addActionListener(e -> hasFullBorderChanged());
|
|
||||||
panel14.add(hasFullBorderCheckBox, "cell 4 0,alignx left,growx 0");
|
|
||||||
|
|
||||||
//---- tabIconsCheckBox ----
|
//---- tabIconsCheckBox ----
|
||||||
tabIconsCheckBox.setText("Tab icons");
|
tabIconsCheckBox.setText("Tab icons");
|
||||||
tabIconsCheckBox.addActionListener(e -> tabIconsChanged());
|
tabIconsCheckBox.addActionListener(e -> tabIconsChanged());
|
||||||
panel14.add(tabIconsCheckBox, "cell 5 0");
|
panel14.add(tabIconsCheckBox, "cell 0 1");
|
||||||
|
|
||||||
//---- tabIconSizeSpinner ----
|
//---- tabIconSizeSpinner ----
|
||||||
tabIconSizeSpinner.setModel(new SpinnerListModel(new String[] {"16", "24", "32", "48", "64"}));
|
tabIconSizeSpinner.setModel(new SpinnerListModel(new String[] {"16", "24", "32", "48", "64"}));
|
||||||
tabIconSizeSpinner.setEnabled(false);
|
tabIconSizeSpinner.setEnabled(false);
|
||||||
tabIconSizeSpinner.addChangeListener(e -> tabIconsChanged());
|
tabIconSizeSpinner.addChangeListener(e -> tabIconsChanged());
|
||||||
panel14.add(tabIconSizeSpinner, "cell 6 0");
|
panel14.add(tabIconSizeSpinner, "cell 1 1");
|
||||||
|
|
||||||
|
//---- customBorderCheckBox ----
|
||||||
|
customBorderCheckBox.setText("Custom border");
|
||||||
|
customBorderCheckBox.addActionListener(e -> customBorderChanged());
|
||||||
|
panel14.add(customBorderCheckBox, "cell 2 1");
|
||||||
|
|
||||||
|
//---- customTabsCheckBox ----
|
||||||
|
customTabsCheckBox.setText("Custom tabs");
|
||||||
|
customTabsCheckBox.addActionListener(e -> customTabsChanged());
|
||||||
|
panel14.add(customTabsCheckBox, "cell 3 1");
|
||||||
|
|
||||||
|
//---- hasFullBorderCheckBox ----
|
||||||
|
hasFullBorderCheckBox.setText("Show content border");
|
||||||
|
hasFullBorderCheckBox.addActionListener(e -> hasFullBorderChanged());
|
||||||
|
panel14.add(hasFullBorderCheckBox, "cell 4 1,alignx left,growx 0");
|
||||||
}
|
}
|
||||||
panel9.add(panel14, cc.xywh(1, 11, 3, 1));
|
panel9.add(panel14, cc.xywh(1, 11, 3, 1));
|
||||||
}
|
}
|
||||||
@@ -353,12 +424,15 @@ public class FlatContainerTest
|
|||||||
private JTabbedPane tabbedPane2;
|
private JTabbedPane tabbedPane2;
|
||||||
private JTabbedPane tabbedPane4;
|
private JTabbedPane tabbedPane4;
|
||||||
private JCheckBox moreTabsCheckBox;
|
private JCheckBox moreTabsCheckBox;
|
||||||
|
private JSpinner moreTabsSpinner;
|
||||||
private JCheckBox tabScrollCheckBox;
|
private JCheckBox tabScrollCheckBox;
|
||||||
private JCheckBox showTabSeparatorsCheckBox;
|
private JCheckBox showTabSeparatorsCheckBox;
|
||||||
private JCheckBox hideContentSeparatorCheckBox;
|
private JCheckBox hideContentSeparatorCheckBox;
|
||||||
private JCheckBox hasFullBorderCheckBox;
|
|
||||||
private JCheckBox tabIconsCheckBox;
|
private JCheckBox tabIconsCheckBox;
|
||||||
private JSpinner tabIconSizeSpinner;
|
private JSpinner tabIconSizeSpinner;
|
||||||
|
private JCheckBox customBorderCheckBox;
|
||||||
|
private JCheckBox customTabsCheckBox;
|
||||||
|
private JCheckBox hasFullBorderCheckBox;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
|
|
||||||
//---- class Tab1Panel ----------------------------------------------------
|
//---- class Tab1Panel ----------------------------------------------------
|
||||||
|
|||||||
@@ -131,8 +131,8 @@ new FormModel {
|
|||||||
} )
|
} )
|
||||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
"$layoutConstraints": "insets 0,hidemode 3"
|
"$layoutConstraints": "insets 0,hidemode 3"
|
||||||
"$columnConstraints": "[][][][fill][][fill][fill]"
|
"$columnConstraints": "[][fill][][][fill]"
|
||||||
"$rowConstraints": "[center]"
|
"$rowConstraints": "[center][]"
|
||||||
} ) {
|
} ) {
|
||||||
name: "panel14"
|
name: "panel14"
|
||||||
"opaque": false
|
"opaque": false
|
||||||
@@ -147,6 +147,20 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 0"
|
"value": "cell 0 0"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JSpinner" ) {
|
||||||
|
name: "moreTabsSpinner"
|
||||||
|
"model": new javax.swing.SpinnerNumberModel {
|
||||||
|
minimum: 0
|
||||||
|
value: 4
|
||||||
|
}
|
||||||
|
"enabled": false
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "moreTabsSpinnerChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 0"
|
||||||
|
} )
|
||||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
name: "tabScrollCheckBox"
|
name: "tabScrollCheckBox"
|
||||||
"text": "Use scroll layout"
|
"text": "Use scroll layout"
|
||||||
@@ -156,7 +170,7 @@ new FormModel {
|
|||||||
}
|
}
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabScrollChanged", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabScrollChanged", false ) )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 0,alignx left,growx 0"
|
"value": "cell 2 0,alignx left,growx 0"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
name: "showTabSeparatorsCheckBox"
|
name: "showTabSeparatorsCheckBox"
|
||||||
@@ -166,7 +180,7 @@ new FormModel {
|
|||||||
}
|
}
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTabSeparatorsChanged", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTabSeparatorsChanged", false ) )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 2 0"
|
"value": "cell 3 0"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
name: "hideContentSeparatorCheckBox"
|
name: "hideContentSeparatorCheckBox"
|
||||||
@@ -176,17 +190,7 @@ new FormModel {
|
|||||||
}
|
}
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hideContentSeparatorChanged", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hideContentSeparatorChanged", false ) )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 3 0"
|
"value": "cell 4 0"
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
|
||||||
name: "hasFullBorderCheckBox"
|
|
||||||
"text": "Show content border"
|
|
||||||
auxiliary() {
|
|
||||||
"JavaCodeGenerator.variableLocal": false
|
|
||||||
}
|
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hasFullBorderChanged", false ) )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 4 0,alignx left,growx 0"
|
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
name: "tabIconsCheckBox"
|
name: "tabIconsCheckBox"
|
||||||
@@ -196,7 +200,7 @@ new FormModel {
|
|||||||
}
|
}
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabIconsChanged", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabIconsChanged", false ) )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 5 0"
|
"value": "cell 0 1"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JSpinner" ) {
|
add( new FormComponent( "javax.swing.JSpinner" ) {
|
||||||
name: "tabIconSizeSpinner"
|
name: "tabIconSizeSpinner"
|
||||||
@@ -215,7 +219,37 @@ new FormModel {
|
|||||||
}
|
}
|
||||||
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "tabIconsChanged", false ) )
|
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "tabIconsChanged", false ) )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 6 0"
|
"value": "cell 1 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "customBorderCheckBox"
|
||||||
|
"text": "Custom border"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customBorderChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "customTabsCheckBox"
|
||||||
|
"text": "Custom tabs"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customTabsChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 3 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "hasFullBorderCheckBox"
|
||||||
|
"text": "Show content border"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hasFullBorderChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 4 1,alignx left,growx 0"
|
||||||
} )
|
} )
|
||||||
}, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) {
|
}, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) {
|
||||||
"gridY": 11
|
"gridY": 11
|
||||||
|
|||||||
Reference in New Issue
Block a user