UI para nuestro RPG: Parte 1
Diseño de la Interfaz Gráfica para nuestro RPG
Hasta ahora hemos visto cómo crear componentes personalizados y manejar eventos en Swing, lo que nos ha dado una base sólida para comenzar a diseñar la interfaz gráfica de nuestro RPG. En esta sección, comenzaremos a construir la ventana principal de nuestro juego y los componentes básicos para la gestión de personajes.
Ventana de Inicio, Carga y Creación de Personajes
Para la ventana de inicio, carga y creación de personajes, podemos diseñar una interfaz que permita a los jugadores seleccionar entre crear un nuevo personaje o cargar uno existente. Esto se puede lograr utilizando componentes como JButton para las opciones de creación y carga, y JPanel para organizar los componentes en la ventana, y JLabel para mostrar información relevante.
Entonces, podríamos tener una ventana principal con un título, cuatro paneles para los slots de personajes, y botones para crear, cargar o eliminar personajes. Cada panel de personaje podría mostrar información básica del personaje, como su nombre, clase, y nivel.
Por consiguiente, la interfaz ser veriá algo así:

Componentes para la Gestión de Personajes
Para la gestión de la interfaz anterior, necesitamos lo siguientes componentes:
- JFrame: Para la ventana principal del juego.
- JPanel: Para organizar los componentes dentro de la ventana.
- JLabel: Para mostrar el Slot de personaje.
- JLabel: Para mostrar los atributos del personaje (nombre, clase, nivel).
- JButton: Para crear, cargar o eliminar personajes.
- JOptionPane: Para mostrar diálogos de creación y carga de personajes.
Estructura de carpetas para la Interfaz Gráfica
Para mantener nuestro proyecto organizado, podemos seguir una estructura de carpetas que separe claramente los diferentes componentes de la interfaz gráfica. De tal razón que la estructura de carpetas podría ser la siguiente:
📦 RPG Project
├─ resources
└── src
└─ app
└─ game
└─ rpg
├─ ui
│ └─ components
│ ├─ borders
│ ├─ frames
│ ├─ panels
│ ├─ buttons
│ ├─ labels
│ ├─ dialogs
│ ├─ delegates
│ ├─ listeners
│ └─ utils
├─ entities
├─ controllers
├─ views
└─ models
©generated by Project Tree Generator
Los colores de la interfaz gráfica
En cierta medida, el diseño de la interfaz gráfica de nuestro RPG también puede beneficiarse de una paleta de colores bien definida. Para mantener una apariencia coherente y atractiva, podemos elegir colores que se ajusten al tema de nuestro juego. Por ejemplo, podríamos optar por tonos oscuros y cálidos para un RPG de fantasía, o colores más brillantes y vibrantes para un RPG de ciencia ficción. Además, es importante considerar la accesibilidad y asegurarse de que los colores elegidos sean legibles y no causen fatiga visual a los jugadores.
Por consiguiente definiremos una paleta de colores que incluya colores para el fondo, los botones, los textos y los bordes. Esto nos ayudará a mantener una apariencia consistente en toda la interfaz gráfica y a crear una experiencia visual atractiva para los jugadores.
package app.game.rpg.utils;
import java.awt.*;
public class ColorPalette {
public static Color GREEN_TOP = new Color(35, 165, 35);
public static Color GREEN_BOTTOM = new Color(15, 73, 15);
public static Color GREEN_HOVER_TOP = GREEN_TOP.brighter();
public static Color GREEN_HOVER_BOTTOM = GREEN_BOTTOM.brighter();
public static Color GREEN_PRESSED_TOP = GREEN_TOP.darker();
public static Color GREEN_PRESSED_BOTTOM = GREEN_BOTTOM.darker();
public static Color RED_TOP = new Color(191, 37, 37);
public static Color RED_BOTTOM = new Color(80, 16, 16);
public static Color RED_HOVER_TOP = RED_TOP.brighter();
public static Color RED_HOVER_BOTTOM = RED_BOTTOM.brighter();
public static Color RED_PRESSED_TOP = RED_TOP.darker();
public static Color RED_PRESSED_BOTTOM = RED_BOTTOM.darker();
public static Color BLUE_TOP = new Color(10, 111, 178);
public static Color BLUE_BOTTOM = new Color(5, 55, 89);
public static Color BLUE_HOVER_TOP = BLUE_TOP.brighter();
public static Color BLUE_HOVER_BOTTOM = BLUE_BOTTOM.brighter();
public static Color BLUE_PRESSED_TOP = BLUE_TOP.darker();
public static Color BLUE_PRESSED_BOTTOM = BLUE_BOTTOM.darker();
public static Color BORDER_LIGHT = new Color(255, 215, 0);
public static Color BORDER_DARK = new Color(128, 64, 0);
}
Como podrás notar, hemos definido una clase ColorPalette que contiene colores para diferentes estados de los botones (normal, hover y pressed) en tonos verdes, rojos y azules, así como colores para los bordes. Esto nos permitirá mantener una apariencia consistente en toda la interfaz gráfica de nuestro RPG y facilitará la aplicación de estilos a los componentes de la interfaz. En las siguientes secciones, utilizaremos esta paleta de colores para diseñar los botones y otros componentes de la interfaz gráfica de nuestro RPG, asegurándonos de que se vean atractivos y coherentes con el tema de nuestro juego.
Definiendo el Border redondeado para los componentes de la interfaz gráfica
Para darle un aspecto más moderno y atractivo a los componentes de la interfaz gráfica de nuestro RPG, podemos definir un border redondeado que se aplicará a los botones y otros elementos de la interfaz. Esto se puede lograr creando una clase que implemente la interfaz Border de Swing y utilizando la clase Graphics2D para dibujar un borde redondeado alrededor de los componentes.
package app.game.rpg.ui.components.borders;
import javax.swing.border.Border;
import java.awt.*;
/**
* RPGRoundedBorder es una clase personalizada que implementa la interfaz Border para crear un borde redondeado con un degradado de color dorado. Este borde se puede aplicar a los paneles de los personajes en la interfaz gráfica de nuestro RPG para mejorar su apariencia.
*/
public class RPGRoundedBorder implements Border {
/**
* Grosor del borde que se dibujará alrededor del componente.
*/
private final int thickness;
/**
* Radio de las esquinas redondeadas del borde.
*/
private final int radius;
private final Color startColor;
private final Color endColor;
/**
* Constructor para crear un borde redondeado con un degradado de color dorado.
*
* @param thickness El grosor del borde.
* @param radius El radio de las esquinas redondeadas.
*/
public RPGRoundedBorder(int thickness, int radius) {
this.thickness = thickness;
this.radius = radius;
this.startColor = new Color(255, 215, 0);
this.endColor = new Color(180, 140, 0);
}
/**
* Constructor para crear un borde redondeado con un degradado de color personalizado.
*
* @param thickness El grosor del borde.
* @param radius El radio de las esquinas redondeadas.
* @param startColor El color de inicio del degradado.
* @param endColor El color de fin del degradado.
*/
public RPGRoundedBorder(int thickness, int radius, Color startColor, Color endColor) {
this.thickness = thickness;
this.radius = radius;
this.startColor = startColor;
this.endColor = endColor;
}
/**
* Función que se encargará de dibujar el borde redondeado con un degradado de color dorado alrededor del componente.
*
* @param c El componente al que se le aplicará el borde.
* @param g El objeto Graphics utilizado para dibujar el borde.
* @param x La coordenada x del borde.
* @param y La coordenada y del borde.
* @param width El ancho del borde.
* @param height La altura del borde.
*/
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
// Crear un objeto Graphics2D a partir del objeto Graphics proporcionado para tener un control más avanzado sobre el dibujo.
Graphics2D g2 = (Graphics2D) g.create();
// Establecer antialiasing para mejorar la calidad del dibujo
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// Crear un degradado de color dorado para el borde, que va desde un tono más claro en la parte superior a un tono más oscuro en la parte inferior.
// Toma en cuenta que puedes ajustar los colores y las coordenadas del degradado para obtener el efecto deseado.
GradientPaint borderGradient = new GradientPaint(
0, 0, startColor,
0, height, endColor
);
// Establecer el degradado como el color de pintura para el borde y configurar el grosor del borde utilizando un BasicStroke.
g2.setPaint(borderGradient);
// La clase BasicStroke se utiliza para definir el grosor y el estilo del borde que se dibujará alrededor del componente.
g2.setStroke(new BasicStroke(thickness));
// Dibujar un rectángulo redondeado utilizando la función drawRoundRect, que toma en cuenta el grosor del borde para asegurarse de que el borde se dibuje correctamente alrededor del componente.
// Las formulas para calcular las coordenadas y dimensiones del rectángulo redondeado se basan en el grosor del borde para garantizar que el borde se dibuje dentro de los límites del componente.
g2.drawRoundRect(
x + thickness / 2,
y + thickness / 2,
width - thickness,
height - thickness,
radius,
radius
);
// Indicamos que hemos terminado de dibujar el borde personalizado y liberamos los recursos utilizados por el objeto Graphics2D.
g2.dispose();
}
/**
* Función que devuelve los insets del borde, que son las áreas de espacio alrededor del componente donde el borde se dibujará. En este caso, el borde se dibujará con un grosor igual al valor de thickness en todos los lados del componente.
* Los insets son importantes para asegurarse de que el borde se dibuje correctamente alrededor del componente sin superponerse al contenido del componente.
*
* @param c the component for which this border insets value applies
* @return los insets del borde, que indican el espacio alrededor del componente donde se dibujará el borde.
*/
@Override
public Insets getBorderInsets(Component c) {
return new Insets(thickness, thickness, thickness, thickness);
}
/**
* Función que indica si el borde es opaco o no. En este caso, el borde no es opaco, lo que significa que el fondo del componente será visible a través del borde. Esto es importante para asegurarse de que el borde se integre bien con el diseño general de la interfaz gráfica y no bloquee la visibilidad del contenido del componente.
*
* @return false, indicando que el borde no es opaco y que el fondo del componente será visible a través del borde.
*/
@Override
public boolean isBorderOpaque() {
return false;
}
}
En esta clase RPGRoundedBorder, hemos definido un borde redondeado con un degradado de color dorado que se puede aplicar a los componentes de la interfaz gráfica de nuestro RPG. El constructor permite personalizar el grosor, el radio de las esquinas y los colores del degradado, lo que nos brinda flexibilidad para adaptar el diseño a nuestras necesidades. La función paintBorder se encarga de dibujar el borde utilizando Graphics2D, mientras que las funciones getBorderInsets e isBorderOpaque aseguran que el borde se dibuje correctamente alrededor del componente sin bloquear la visibilidad del contenido. En las siguientes secciones, aplicaremos este borde a los paneles de los personajes y otros componentes de la interfaz gráfica para mejorar su apariencia y coherencia visual.
Estructurando nuestra ventana (Frame) general para el RPG
Para estructurar la ventana principal de nuestro RPG, podemos crear una clase que extienda JFrame y configure el diseño general de la interfaz gráfica. En esta clase, podemos definir un panel principal que contenga los diferentes componentes de la interfaz, como el panel de personajes, el panel de habilidades, el panel de inventario, etc. Además, podemos aplicar el borde redondeado que hemos definido anteriormente para mejorar la apariencia de los componentes. Y para hacer más personalizada la experiencia del usuario, definiremos un panel como barra de estado de la ventana con sus respectivos bótones para minimizar y cerrar la ventana. Esto nos permitirá tener un control total sobre el diseño y la funcionalidad de la ventana principal de nuestro RPG. En las siguientes secciones, implementaremos esta estructura y aplicaremos el borde redondeado a los componentes de la interfaz gráfica para crear una experiencia visual atractiva y coherente.
Creando la Barra de Estado Personalizada
Para crear una barra de estado personalizada en la ventana principal de nuestro RPG, podemos definir un panel que se ubique en la parte superior de la ventana y contenga los botones para minimizar y cerrar la ventana. Este panel puede tener un diseño personalizado que se integre con el tema visual de nuestro RPG, utilizando colores, fuentes y estilos que reflejen la estética del juego. Además, podemos agregar funcionalidad a los botones para que respondan a las acciones del usuario, como minimizar la ventana al hacer clic en el botón de minimizar o cerrar la aplicación al hacer clic en el botón de cerrar. Al implementar esta barra de estado personalizada, mejoraremos la experiencia del usuario al proporcionar una interfaz gráfica más atractiva y funcional para nuestro RPG. En las siguientes secciones, implementaremos esta barra de estado personalizada y la integraremos en la estructura general de la ventana principal de nuestro RPG.
package app.game.rpg.ui.components.panels;
import app.game.rpg.ui.components.buttons.RPGTitleBarButton;
import app.game.rpg.ui.components.buttons.RPGTitleBarButtonType;
import app.game.rpg.ui.components.delegates.RPGTitleBarUI;
import app.game.rpg.ui.components.listeners.RPGWindowDragListener;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
/**
* RPGTitleBar es una clase personalizada que extiende JPanel para crear una barra de título personalizada para la ventana principal de nuestro RPG. Esta barra de título incluye botones personalizados para cerrar y minimizar la ventana, y se puede personalizar con diferentes colores y estilos.
*/
public class RPGTitleBar extends JPanel {
/**
* Botón personalizado para cerrar la ventana.
*/
private final RPGTitleBarButton closeButton;
/**
* Botón personalizado para minimizar la ventana.
*/
private final RPGTitleBarButton minimizeButton;
/**
* Referencia al JFrame padre para controlar las acciones de minimizar y cerrar la ventana.
*/
private final JFrame parentFrame;
/**
* Punto inicial para el arrastre de la ventana, utilizado para permitir que el usuario mueva la ventana arrastrando la barra de título.
*/
private Point initialClick;
/**
* Constructor para crear una barra de título personalizada con botones de cerrar y minimizar.
*
* @param frame El JFrame al que se le aplicará la barra de título personalizada.
* @param title El texto que se mostrará en la barra de título.
*/
public RPGTitleBar(JFrame frame, String title) {
// Establece un diseño de borde para organizar los componentes de la barra de título. Recuerda que puedes personalizar los colores y estilos de la barra de título modificando los parámetros del constructor RPGTitleBarUI.
setUI(new RPGTitleBarUI(new Color(6, 44, 155), new Color(1, 36, 79)));
setPreferredSize(new Dimension(frame.getWidth(), 30));
parentFrame = frame;
closeButton = new RPGTitleBarButton(RPGTitleBarButtonType.CLOSE);
minimizeButton = new RPGTitleBarButton(RPGTitleBarButtonType.MINIMIZE);
initComponents(title);
addListeners();
}
/**
* Función privada para inicializar los componentes de la barra de título, incluyendo el título y los botones de cerrar y minimizar.
*
* @param title El texto que se mostrará en la barra de título.
*/
private void initComponents(String title) {
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
buttonPanel.setOpaque(false);
buttonPanel.add(minimizeButton);
buttonPanel.add(closeButton);
JLabel titleLabel = new JLabel(title);
titleLabel.setBorder(new EmptyBorder(0, 10, 0, 0));
titleLabel.setForeground(Color.WHITE);
add(titleLabel, BorderLayout.WEST);
add(buttonPanel, BorderLayout.EAST);
}
/**
* Función privada para agregar los listeners a los botones de cerrar y minimizar, permitiendo que la barra de título controle las acciones de la ventana principal.
*/
private void addListeners() {
closeButton.addActionListener(e -> System.exit(0));
minimizeButton.addActionListener(e -> parentFrame.setState(JFrame.ICONIFIED));
}
/**
* Función pública para habilitar el arrastre de la ventana al hacer clic y arrastrar la barra de título. Esto permite que el usuario mueva la ventana arrastrando la barra de título, proporcionando una experiencia de usuario más fluida y personalizada.
*/
public void enableWindowDragging() {
RPGWindowDragListener dragListener = new RPGWindowDragListener(parentFrame);
addMouseListener(dragListener);
addMouseMotionListener(dragListener);
}
}
En este código, hemos creado la clase RPGTitleBar que extiende JPanel para crear una barra de título personalizada para la ventana principal de nuestro RPG. Esta barra de título incluye botones personalizados para cerrar y minimizar la ventana, y se puede personalizar con diferentes colores y estilos. Además, hemos agregado funcionalidad para permitir que el usuario arrastre la ventana al hacer clic y arrastrar la barra de título, proporcionando una experiencia de usuario más fluida y personalizada.
package app.game.rpg.ui.components.delegates;
import javax.swing.*;
import java.awt.*;
/**
* RPGTitleBarUI es una clase personalizada que extiende RPGPanelUI para proporcionar un panel de título con un borde redondeado
* y degradado de color, diseñado específicamente para la barra de título de nuestra interfaz gráfica de juego RPG. Este panel se puede utilizar
* para mostrar el título del juego o cualquier información relevante en la parte superior de la ventana del juego.
*/
public class RPGTitleBarUI extends RPGPanelUI {
/**
* Constructor para crear un objeto Panel de título con el color de inicio y final del degradado.
*
* @param startColor Color inicial seleccionado para el degradado del panel.
* @param endColor Color final seleccionado para el degradado del panel.
*/
public RPGTitleBarUI(Color startColor, Color endColor) {
super(startColor, endColor);
}
/**
* Función que permite aplicar características por defecto a un JPanel. En nuestro caso, eliminamos su borde y un layout box
* para que los componentes a agregar se coloquen de forma vertical.
*
* @param p an instance of {@code JPanel}
*/
@Override
protected void installDefaults(JPanel p) {
super.installDefaults(p);
p.setBorder(null);
p.setLayout(new BorderLayout());
}
/**
* Función que permite dibujar el fondo degradado del panel RPGTitleBarUI en un componente {@code JComponent}.
* En nuestro caso usamos un degradado lineal para dibujar una textura con un color inicial y final,
* desde la parte superior del componente hasta la mitad de su altura.
*
* @param c an instance of {@code JComponent}
* @return an instance of {@code Paint} representing the gradient to be used for painting the background of the component.
*/
@Override
protected Paint getPaintMethod(JComponent c) {
int x1 = 0, y1 = 0;
int x2 = 0, y2 = c.getHeight() / 2;
return new GradientPaint(x1, y1, startColor, x2, y2, endColor);
}
}
En este código, hemos creado la clase RPGTitleBarUI que extiende RPGPanelUI para proporcionar un panel de título con un borde redondeado y degradado de color, diseñado específicamente para la barra de título de nuestra interfaz gráfica de juego RPG. Este panel se puede utilizar para mostrar el título del juego o cualquier información relevante en la parte superior de la ventana del juego. Hemos personalizado el método installDefaults para eliminar el borde del panel y establecer un layout de tipo BorderLayout, y el método getPaintMethod para dibujar un fondo degradado utilizando un GradientPaint que va desde la parte superior del componente hasta la mitad de su altura, proporcionando un efecto visual atractivo para la barra de título.
package app.game.rpg.ui.components.buttons;
import app.game.rpg.ui.components.delegates.RPGTitleBarButtonUI;
import javax.swing.*;
import java.awt.*;
/**
* RPGTitleBarButton es una clase personalizada que extiende JButton para crear botones personalizados para la barra de título de la ventana principal de nuestro RPG. Estos botones pueden ser de tipo cerrar, minimizar, maximizar o restaurar, y se pueden personalizar con diferentes colores y estilos.
*/
public class RPGTitleBarButton extends JButton {
/**
* Tipo del botón, que determina su función (cerrar, minimizar, maximizar o restaurar) y su apariencia.
*/
private RPGTitleBarButtonType type;
/**
* Constructor para crear un botón personalizado para la barra de título, basado en el tipo especificado.
*
* @param type El tipo del botón, que determina su función (cerrar, minimizar, maximizar o restaurar) y su apariencia. Este parámetro es esencial para configurar correctamente el botón y su comportamiento en la barra de título personalizada.
*/
public RPGTitleBarButton(RPGTitleBarButtonType type) {
this.type = type;
switch (type) {
case CLOSE -> setBackground(new Color(200, 60, 60));
case MINIMIZE -> setBackground(new Color(60, 60, 200));
case MAXIMIZE, RESTORE -> setBackground(new Color(60, 200, 60));
}
setIcon(type.getSymbol());
setUI(new RPGTitleBarButtonUI());
}
/**
* Función para actualizar el tipo del botón y su apariencia en la barra de título personalizada. Esta función permite cambiar dinámicamente el tipo del botón (por ejemplo, de maximizar a restaurar) y actualizar su icono y estilo en consecuencia.
*
* @param type El nuevo tipo del botón, que determina su función (cerrar, minimizar, maximizar o restaurar) y su apariencia. Este parámetro es esencial para actualizar correctamente el botón y su comportamiento en la barra de título personalizada.
*/
public void setType(RPGTitleBarButtonType type) {
this.type = type;
setIcon(type.getSymbol());
revalidate();
repaint();
}
}
En este código, hemos creado la clase RPGTitleBarButton que extiende JButton para crear botones personalizados para la barra de título de la ventana principal de nuestro RPG. Estos botones pueden ser de tipo cerrar, minimizar, maximizar o restaurar, y se pueden personalizar con diferentes colores y estilos. El constructor de la clase toma un parámetro type que determina el tipo del botón y su apariencia, y se utiliza un switch para configurar el color de fondo y el icono del botón según su tipo. Además, hemos agregado una función setType que permite actualizar dinámicamente el tipo del botón y su apariencia en la barra de título personalizada.
package app.game.rpg.ui.components.buttons;
import jiconfont.IconCode;
import jiconfont.icons.font_awesome.FontAwesome;
import jiconfont.swing.IconFontSwing;
import javax.swing.*;
import java.awt.*;
/**
* Enum RPGTitleBarButtonType define los tipos de botones que se pueden utilizar en la barra de título personalizada de la ventana principal de nuestro RPG. Cada tipo de botón tiene un icono asociado que se muestra en la barra de título, y se puede personalizar con diferentes colores y estilos.
*/
public enum RPGTitleBarButtonType {
CLOSE("WINDOW_CLOSE"),
MINIMIZE("WINDOW_MINIMIZE"),
RESTORE("WINDOW_RESTORE"),
MAXIMIZE("WINDOW_MAXIMIZE");
/**
* Icono asociado al tipo de botón, que se muestra en la barra de título personalizada. Este icono se genera utilizando la biblioteca IconFontSwing y el conjunto de iconos FontAwesome, lo que permite una apariencia visual atractiva y coherente con el estilo del RPG.
*/
private final Icon symbol;
/**
* Constructor para crear un tipo de botón con un icono asociado. El constructor recibe un símbolo como parámetro, que se utiliza para generar el icono correspondiente utilizando la biblioteca IconFontSwing y el conjunto de iconos FontAwesome. Este proceso permite que cada tipo de botón tenga un icono visualmente distintivo que se muestra en la barra de título personalizada.
*
* @param symbol El símbolo que se utiliza para generar el icono asociado al tipo de botón. Este parámetro es esencial para configurar correctamente el icono que se mostrará en la barra de título personalizada, proporcionando una experiencia de usuario más atractiva y coherente con el estilo del RPG.
*/
RPGTitleBarButtonType(String symbol) {
IconFontSwing.register(FontAwesome.getIconFont());
IconCode iconCode = FontAwesome.valueOf(symbol);
this.symbol = IconFontSwing.buildIcon(iconCode, 20, Color.WHITE);
}
/**
* Función para obtener el icono asociado al tipo de botón. Esta función devuelve el icono que se muestra en la barra de título personalizada, lo que permite que cada tipo de botón tenga una apariencia visual distintiva y coherente con el estilo del RPG.
*
* @return El icono asociado al tipo de botón, que se muestra en la barra de título personalizada. Este valor es esencial para configurar correctamente la apariencia visual del botón en la barra de título personalizada, proporcionando una experiencia de usuario más atractiva y coherente con el estilo del RPG.
*/
public Icon getSymbol() {
return symbol;
}
}
En este código, hemos creado el enum RPGTitleBarButtonType que define los tipos de botones que se pueden utilizar en la barra de título personalizada de la ventana principal de nuestro RPG. Cada tipo de botón tiene un icono asociado que se muestra en la barra de título, y se puede personalizar con diferentes colores y estilos. El constructor del enum recibe un símbolo como parámetro, que se utiliza para generar el icono correspondiente utilizando la biblioteca IconFontSwing y el conjunto de iconos FontAwesome. Además, hemos agregado una función getSymbol que devuelve el icono asociado al tipo de botón, lo que permite configurar correctamente la apariencia visual del botón en la barra de título personalizada.
package app.game.rpg.ui.components.listeners;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class RPGWindowDragListener extends MouseAdapter {
/**
* Punto inicial para el arrastre de la ventana, utilizado para permitir que el usuario mueva la ventana arrastrando la barra de título.
*/
private Point initialClick;
/**
* Referencia al JFrame padre para controlar las acciones de minimizar y cerrar la ventana.
*/
private final JFrame parentFrame;
/**
* Constructor para crear un listener que permite arrastrar la ventana al hacer clic y arrastrar en la barra de título personalizada.<br/>
* Este listener se utiliza para permitir que el usuario mueva la ventana arrastrando la barra de título personalizada, proporcionando una experiencia de usuario más fluida y personalizada.<br/>
* El constructor recibe un JFrame como parámetro, que es esencial para que el listener pueda controlar la posición de la ventana durante el arrastre. Sin esta referencia al JFrame, el listener no podría actualizar la posición de la ventana correctamente.
*
* @param frame El JFrame al que se le aplicará el listener para permitir el arrastre de la ventana. Este parámetro es esencial para que el listener pueda controlar la posición de la ventana durante el arrastre.
*/
public RPGWindowDragListener(JFrame frame) {
parentFrame = frame;
}
/**
* Función que se ejecuta cuando el usuario presiona el mouse en la barra de título personalizada. Esta función captura la posición inicial del clic, que se utilizará como referencia para calcular el desplazamiento de la ventana durante el arrastre.
*
* @param e El evento de mouse que contiene información sobre la posición del clic y otros detalles relacionados con la interacción del usuario.
*/
@Override
public void mousePressed(MouseEvent e) {
initialClick = e.getPoint();
}
/**
* Función que se ejecuta cuando el usuario arrastra el mouse después de presionar en la barra de título personalizada. Esta función calcula la nueva posición de la ventana basándose en el desplazamiento del mouse desde la posición inicial capturada en el método mousePressed.
*
* @param e El evento de mouse que contiene información sobre la posición actual del mouse y otros detalles relacionados con la interacción del usuario.
*/
@Override
public void mouseDragged(MouseEvent e) {
Point current = e.getLocationOnScreen();
parentFrame.setLocation(current.x - initialClick.x, current.y - initialClick.y);
}
}
En este código, hemos creado la clase RPGWindowDragListener que extiende MouseAdapter para permitir que el usuario arrastre la ventana al hacer clic y arrastrar en la barra de título personalizada. El constructor de la clase recibe un JFrame como parámetro, que es esencial para que el listener pueda controlar la posición de la ventana durante el arrastre. La función mousePressed captura la posición inicial del clic, mientras que la función mouseDragged calcula la nueva posición de la ventana basándose en el desplazamiento del mouse desde la posición inicial capturada. Este listener proporciona una experiencia de usuario más fluida y personalizada al permitir que el usuario mueva la ventana arrastrando la barra de título personalizada.
Conclusión
En esta sección, hemos implementado la barra de título personalizada para la ventana principal de nuestro RPG utilizando Java Swing. Hemos creado un enum RPGTitleBarButtonType para definir los tipos de botones que se pueden utilizar en la barra de título personalizada, cada uno con un icono asociado generado utilizando la biblioteca IconFontSwing y el conjunto de iconos FontAwesome. Además, hemos creado la clase RPGWindowDragListener que extiende MouseAdapter para permitir que el usuario arrastre la ventana al hacer clic y arrastrar en la barra de título personalizada. Estas implementaciones proporcionan una experiencia de usuario más fluida y personalizada al permitir que el usuario interactúe con la ventana de manera más intuitiva y visualmente atractiva. Es importante tener en cuenta que estas implementaciones son solo una parte de la personalización de la interfaz de usuario de nuestro RPG, y se pueden agregar más funcionalidades y personalizaciones según las necesidades del proyecto. En la próxima sección, continuaremos con la implementación de otros componentes de la interfaz de usuario para mejorar aún más la experiencia de usuario en nuestro RPG.
Los delegadores en Swing
Cómo usar delegadores en Swing para manejar eventos y mejorar la interacción de tus interfaces.
UI para nuestro RPG: Parte 2
En esta segunda parte, continuaremos desarrollando la interfaz de usuario para nuestro RPG, enfocándonos en la implementación de Paneles, Botones y otros elementos interactivos.