UIForJFrame.java
package swingtree;
import org.jspecify.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.Objects;
import java.util.Optional;
/**
* A declarative builder for {@link JFrame} components.
* Use {@link #show()} at the end of your declaration to display the {@link JFrame} window on the screen.
*
* @param <F> The type of the {@link JFrame} that this builder is responsible for.
*/
public final class UIForJFrame<F extends JFrame> extends UIForAnyWindow<UIForJFrame<F>, F>
{
private final BuilderState<F> _state;
/**
* @param state The {@link BuilderState} modelling how the underlying component is built.
*/
UIForJFrame( BuilderState<F> state ) {
Objects.requireNonNull(state);
_state = state;
}
@Override
protected BuilderState<F> _state() {
return _state;
}
@Override
protected UIForJFrame<F> _newBuilderWithState(BuilderState<F> newState ) {
return new UIForJFrame<>(newState);
}
@Override
protected void _addComponentTo(F thisComponent, Component addedComponent, @Nullable Object constraints) {
thisComponent.add(constraints == null ? null : constraints.toString(), addedComponent);
}
@Override
public void show() {
JFrame frame = get(_state.componentType());
Component[] components = frame.getComponents();
frame.setLocationRelativeTo(null); // Initial centering!v
frame.pack(); // Otherwise some components resize strangely or are not shown at all...
// Make sure that the window is centered on the screen again but with the component:
frame.setLocationRelativeTo(null);
// We set the size to fit the component:
if ( components.length > 0 ) {
Dimension size = frame.getSize();
if ( size == null ) // The frame has no size! It is best to set the size to the preferred size of the component:
size = components[0].getPreferredSize();
if ( size == null ) // The component has no preferred size! It is best to set the size to the minimum size of the component:
size = components[0].getMinimumSize();
if ( size == null ) // The component has no minimum size! Let's just look up the size of the component:
size = components[0].getSize();
frame.setSize(size);
}
frame.setVisible(true);
}
@Override protected Optional<JRootPane> _getRootPaneOf(F thisWindow) {
return Optional.ofNullable(thisWindow.getRootPane());
}
@Override
protected void _setTitleOf(F thisWindow, String title) {
thisWindow.setTitle(title);
}
}