MessageDialog.java
package swingtree.dialogs;
import org.jspecify.annotations.Nullable;
import swingtree.UI;
import swingtree.api.IconDeclaration;
import javax.swing.Icon;
import javax.swing.JOptionPane;
import java.awt.Component;
import java.util.Objects;
/**
* An immutable builder class for creating simple message dialogs (errors, warnings, infos...)
* based on the {@link JOptionPane} class, more specifically the
* {@link JOptionPane#showMessageDialog(Component, Object, String, int, Icon)}
* method.
* <p>
* This class is intended to be used as part of the {@link UI} API
* by calling the {@link UI#message(String)} factory method.
*/
public final class MessageDialog
{
public static MessageDialog saying(String text ) {
Objects.requireNonNull(text);
return new MessageDialog(
-1,
"",
text,
null,
null
);
}
private final int _type;
private final String _title;
private final String _message;
private final @Nullable Icon _icon;
private final @Nullable Component _parent;
private MessageDialog(
int type,
String title,
String message,
@Nullable Icon icon,
@Nullable Component parent
) {
_type = type;
_title = title;
_message = message;
_icon = icon;
_parent = parent;
}
/**
* Set the type of the dialog.
* @param type The type of the dialog.
* @return A new {@link MessageDialog} instance with the specified type.
*/
private MessageDialog type( int type ) {
return new MessageDialog(type, _title, _message, _icon, _parent);
}
/**
* Set the title of the dialog.
* @param title The title of the dialog.
* @return A new {@link MessageDialog} instance with the specified title.
*/
public MessageDialog titled( String title ) {
return new MessageDialog(_type, title, _message, _icon, _parent);
}
/**
* Defines the icon which should be displayed alongside the message
* in terms of an {@link IconDeclaration}, which is a constant object holding
* the path to the icon resource and the preferred size of the icon.
* Consider using this over the {@link #icon(Icon)} method
* to avoid resource loading issues as this approach ensures
* that the icon is loaded and cached only once.<br>
* A failure to load the icon will result in the default icon being displayed.
*
* @param icon The icon declaration to find the icon.
* @return A new {@link MessageDialog} instance with the specified icon.
*/
public MessageDialog icon( IconDeclaration icon ) {
Objects.requireNonNull(icon);
return icon.find().map(this::icon).orElse(this);
}
/**
* Set the icon of the dialog as an {@link Icon}.
* Consider using the {@link #icon(IconDeclaration)} method
* to avoid resource loading issues.
*
* @param icon The icon of the dialog.
* @return A new {@link MessageDialog} instance with the specified icon.
*/
public MessageDialog icon( Icon icon ) {
return new MessageDialog(_type, _title, _message, icon, _parent);
}
/**
* Set the icon of the dialog as a path to the icon resource.
* Consider using the {@link #icon(IconDeclaration)} method
* to avoid resource loading issues.
*
* @param path The path to the icon resource.
* @return A new {@link MessageDialog} instance with the specified icon.
*/
public MessageDialog icon( String path ) {
Objects.requireNonNull(path);
return icon(IconDeclaration.of(path));
}
/**
* Set the parent of the dialog.
* @param parent The parent of the dialog.
* @return A new {@link MessageDialog} instance with the specified parent.
*/
public MessageDialog parent( Component parent ) {
return new MessageDialog(_type, _title, _message, _icon, parent);
}
/**
* Show the dialog with the specified configuration
* as an error dialog.
*/
public void showAsError() {
type(JOptionPane.ERROR_MESSAGE).show();
}
/**
* Show the dialog with the specified configuration
* as a warning dialog.
*/
public void showAsWarning() {
type(JOptionPane.WARNING_MESSAGE).show();
}
/**
* Show the dialog with the specified configuration
* as an info dialog.
*/
public void showAsInfo() {
type(JOptionPane.INFORMATION_MESSAGE).show();
}
/**
* Show the dialog with the specified configuration.
*/
public void show() {
UI.run(() -> {
int type = _type;
if ( type == -1 )
type = JOptionPane.INFORMATION_MESSAGE;
Context.summoner.showMessageDialog(
_parent, // parent component, if this is not null then the dialog will be centered on it
_message, // message to display
_title, // title of the dialog displayed in the title bar of the dialog window
type, // type of the dialog (error, warning, info...)
_icon // icon to display in the dialog
);
});
}
}