FlowCell.java
package swingtree.layout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import swingtree.UI;
import swingtree.api.Configurator;
import java.util.Objects;
/**
* This class is an {@link AddConstraint} designed as a
* component constraint for the {@link ResponsiveGridFlowLayout} layout manager,
* allowing you to dynamically adjust the number of grid layout cells
* a particular component can span based on the current parent container's size.<br>
* <p>
* Instances of this are wrapper for a {@link Configurator} lambda that
* processes a {@link FlowCellConf} instance containing an
* array of {@link FlowCellSpanPolicy} instances which
* define at which parent size category how many cells the component should span.<br>
* <p>
* This is intended to be created using the
* {@link UI#AUTO_SPAN(Configurator)} factory method
* as part of a fluent layout configuration oon your UI declarations.<br>
* Here is an example of how a usage of this class might look like:
* <pre>{@code
* UI.panel().withPrefSize(400, 300)
* .withFlowLayout()
* .add(UI.AUTO_SPAN( it->it.small(12).medium(6).large(8) ),
* html("A red cell").withStyle(it->it
* .backgroundColor(UI.Color.RED)
* )
* )
* .add(UI.AUTO_SPAN( it->it.small(12).medium(6).large(4) ),
* html("a green cell").withStyle(it->it
* .backgroundColor(Color.GREEN)
* )
* )
* }</pre>
* In the above example, the {@code it} parameter of the {@code Configurator}
* is an instance of the {@link FlowCellConf} class.
* The {@link Configurator} is called every time the {@link ResponsiveGridFlowLayout} updates the layout
* of the parent container, so that the number of cells a component spans can be adjusted dynamically.<br>
* The {@link swingtree.UIForAnySwing#withFlowLayout()} creates a {@link ResponsiveGridFlowLayout}
* and attaches it to the panel.<br>
* <p><b>
* Note that the {@link FlowCell} configuration may only take effect if the parent
* container has a {@link ResponsiveGridFlowLayout} as a {@link java.awt.LayoutManager} installed.
* </b>
*/
public final class FlowCell implements AddConstraint
{
private static final Logger log = LoggerFactory.getLogger(FlowCell.class);
private final Configurator<FlowCellConf> _configurator;
public FlowCell(Configurator<FlowCellConf> configurator) {
Objects.requireNonNull(configurator);
_configurator = configurator;
}
FlowCellConf fetchConfig(
int maxCells, Size parentSize, ParentSizeClass parentSizeCategory, boolean defaultHeightFill
) {
FlowCellConf conf = new FlowCellConf(
maxCells, parentSize, parentSizeCategory,
new FlowCellSpanPolicy[0], defaultHeightFill,
UI.VerticalAlignment.CENTER
);
try {
return _configurator.configure(conf);
} catch (Exception e) {
log.error(
"Error configuring '"+ FlowCellConf.class.getSimpleName()+"' instance " +
"for '"+ ResponsiveGridFlowLayout.class.getSimpleName() + "' layout.",
e
);
}
return conf;
}
@Override
public Object toConstraintForLayoutManager() {
return this;
}
@Override
public String toString() {
return this.getClass().getSimpleName() + "[" + _configurator + "]";
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
FlowCell that = (FlowCell) obj;
return Objects.equals(_configurator, that._configurator);
}
@Override
public int hashCode() {
return Objects.hash(_configurator);
}
}