StylableComponent.java
- package swingtree.style;
- import javax.swing.JComponent;
- import javax.swing.plaf.ComponentUI;
- import java.awt.Graphics;
- import java.awt.Graphics2D;
- import java.util.function.Consumer;
- /**
- * Implementations of this interface are SwingTree native components
- * which enjoy the full support of the style API.
- * Regular Swing components can be styled on most layers
- * but not all. The {@link swingtree.UI.Layer#BACKGROUND} and
- * {@link swingtree.UI.Layer#FOREGROUND} layers are not supported
- * for some components for which SwingTree tries to install a
- * custom UI delegate. <br>
- * This however is prone to side effects and can cause issues
- * with third party look and feels. <br>
- * For full support of the style API for your custom components
- * you should implement this interface.
- */
- public interface StylableComponent
- {
- /**
- * Certain style configurations require SwingTree to install a
- * custom UI delegate. This method is used to set the UI delegate
- * for the component but without triggering side effects like
- * the former UI being uninstalled (which itself can cause
- * a lot of undesired side effects).
- * <p>
- * <b>This method is not intended to be called by client code!
- * It exists for internal use only and unfortunately cannot be
- * protected or private due to the nature of the Swing API.</b>
- * <p>
- * The implementation of this method is expected to look like this:
- * <pre>
- * {@literal @}Override
- * public void setUISilently(ComponentUI ui){
- * this.ui = ui; // no side effects
- * }
- * </pre>
- * @param ui the UI delegate to set for the component
- * without triggering side effects.
- */
- void setUISilently( ComponentUI ui );
- /**
- * This method is expected to be implemented as follows
- * within a component extension which ought to be made compatible
- * with SwingTree.
- * <pre>
- * {@literal @}Override
- * public void paint(Graphics g){
- * paintBackground(g, ()->super.paint(g));
- * }
- * </pre>
- * @param g the graphics context to paint on,
- * obtained from the component's {@link JComponent#paint(Graphics)} method.
- */
- void paint( Graphics g );
- /**
- * This method is expected to be implemented as follows:
- * <pre>
- * {@literal @}Override
- * public void paintChildren(Graphics g){
- * paintForeground(g, ()->super.paintChildren(g));
- * }
- * </pre>
- * @param g the graphics context to paint on,
- * obtained from the component's {@code JComponent::paintChildren(Graphics)} method.
- */
- void paintChildren( Graphics g );
- /**
- * <b>
- * This default method is not intended to be overridden by client code!
- * It delegates the painting to the library internal {@link ComponentExtension}.
- * </b>
- *
- * @param g The graphics context to paint on.
- * @param superPaint The super.paint() method to call.
- */
- /*final*/ default void paintBackground( Graphics g, Consumer<Graphics> superPaint ) {
- if ( this instanceof JComponent ) {
- ComponentExtension.from((JComponent) this).paintBackgroundIfNeeded( g, superPaint );
- }
- else
- throw new UnsupportedOperationException( "This interface is only intended for JComponent implementations" );
- }
- /**
- * <b>
- * This default method is not intended to be overridden by client code!
- * It delegates the painting to the library internal {@link ComponentExtension}.
- * </b>
- *
- * @param g The graphics context to paint on.
- * @param superPaint The super.paintChildren() method to call.
- */
- /*final*/ default void paintForeground( Graphics g, Consumer<Graphics> superPaint ) {
- if ( this instanceof JComponent ) {
- ComponentExtension.from((JComponent) this).paintForeground( (Graphics2D) g, superPaint );
- }
- else
- throw new UnsupportedOperationException( "This interface is only intended for JComponent implementations" );
- }
- }