Saltar al contenido
CrossFly es 100% open sourceSíguenos en GitHub
CrossFlyCrossFly
Empezar

Esta página fue traducida automáticamente del portugués y puede contener errores. La versión en portugués es la canónica.

Dibujo personalizado (onPaint)

Cuando ningún widget sirve, crea un Component y sobrescribe onPaint(Paint paint). Las coordenadas son locales (0,0 = esquina superior izquierda; width/height son el tamaño del componente).

Ejemplo completo (copiar, pegar y ejecutar)

package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.graphics.*;    // Paint, GRect, Font
import dev.crossfly.ui.style.*;       // Styles

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   /** Componente custom: dibuja un "badge" (píldora coloreada con un número). */
   static class Badge extends Component
   {
      private int valor;

      Badge(int valor) { this.valor = valor; }

      @Override
      public void onPaint(Paint paint) throws Exception
      {
         // Coordenadas LOCALES: (0,0) = arriba-izquierda; width/height = tamaño del componente.
         GRect r = new GRect()
            .bounds(0, 0, width, height)
            .fill(0xFFE53935)          // rojo ARGB
            .radius(height / 2);       // píldora / círculo
         paint.rect(r);

         Font f = Styles.font;
         String s = String.valueOf(valor);
         int tx = (width - (int) f.width(s)) / 2;
         int ty = (height - f.scaledHeight()) / 2;
         paint.text(s, tx, ty, 0xFFFFFFFF, f);   // texto blanco centrado
      }
   }

   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());
      Badge badge = new Badge(7);
      add(LAY_AUTO, badge);   // agrega el componente custom a la pantalla
   }
}

Los fragmentos siguientes muestran solo el núcleo (lo que va dentro de onShow()). Para ejecutar, colócalos en el esqueleto MainWindow de arriba.

Esqueleto

public class Badge extends Component {
   private int valor;
   public Badge(int valor) { this.valor = valor; }

   @Override public void onPaint(Paint paint) throws Exception {
      // fondo redondo relleno
      GRect r = new GRect()
         .bounds(0, 0, width, height)
         .fill(0xFFE53935)               // rojo
         .radius(height / 2);            // píldora/círculo
      paint.rect(r);

      // texto centrado
      Font f = Styles.font;
      String s = String.valueOf(valor);
      int tx = (width - (int) f.width(s)) / 2;
      int ty = (height - f.scaledHeight()) / 2;
      paint.text(s, tx, ty, 0xFFFFFFFF, f);
   }
}
// para redibujar tras cambiar 'valor': repaint();

Primitivas de Paint

Llamada Dibuja
paint.rect(GRect r) rectángulo (relleno/borde/esquinas/sombra) — configura el GRect
paint.text(String, x, y, color, Font) texto
paint.line(x1, y1, x2, y2, color, thick) línea
paint.image(Image, x, y[, w, h]) imagen
paint.polyline(GLines) / paint.polygon(GLines) polilínea / polígono

GRect — el rectángulo configurable

Fluido: .bounds(x,y,w,h) · .fill(color) · .border(color, thick) · .radius(r) / .radius(tl,tr,br,bl). Después paint.rect(gr).

GRect card = new GRect().bounds(0, 0, width, height)
   .fill(0xFFFFFFFF).border(0xFFE0E0E0, 1).radius(8);
paint.rect(card);

Buenas prácticas

  • Dibuja relativo a width/height (no valores fijos) — mantiene la responsividad.
  • Reaprovecha objetos GRect/Font (campos) en lugar de asignar por frame.
  • Llama repaint() cuando el estado que afecta al dibujo cambie (el render es bajo demanda).

Errores comunes

  • Usar coordenadas absolutas de pantalla en el onPaint — son locales al componente.
  • Olvidar repaint() después de cambiar el dato dibujado.
  • Pasar el color como objeto — los colores son int ARGB (la clase Color no existe).

Véase también

¿Te resultó útil esta página?