# ImageView

> Exibe uma Image com modo de escala (ImageSize) e alinhamento configuráveis.

Source: https://crossfly.dev/pt/docs/ui/widgets/imageview — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# ImageView

`ImageView` renderiza uma [`Image`](/docs/ui/images-and-graphics) dentro dos limites do componente, com o modo de escala controlado pelo enum [`ImageSize`](/docs/reference) e alinhamento horizontal/vertical via `Position`. É a forma declarativa de mostrar uma imagem fixa (foto, capa, logo) num layout.

Internamente ele mantém uma cópia **escalada em cache** (`ResizeMode.STRETCH`, `ResizeQuality.FAST`) para não redimensionar a cada frame; a cache é invalidada ao trocar a imagem, o modo de escala ou o tamanho.

> 🟢 · **Pacote:** `dev.crossfly.ui` · **Estende:** `Component` · **Estilo:** `ComponentStyle` (usa `ingap` para margem interna)

## Quando usar
- Exibir uma imagem fixa num layout: foto, capa, logo, avatar.
- Ajustar como a imagem preenche o espaço (aspect ratio, cover, stretch).

## Quando NÃO usar
- Animação por frame, escala contínua variável ou desenho composto → faça um `Component` próprio com `onPaint` chamando `paint.image(...)` diretamente (ver [`images-and-graphics/`](/docs/ui/images-and-graphics)).
- Imagem de **fundo** de outro componente → use o `BackgroundImage` do próprio `Component` (Cap. 18).

## Aparência
A imagem é centrada por padrão dentro da área interna (após `ingap`) e escalada conforme o `ImageSize`:

| `ImageSize` | Comportamento |
|---|---|
| `ORIGINAL` | tamanho natural, sem escala |
| `RATIO` | escala uniforme para **caber** dentro dos limites (letter-box) — **padrão** |
| `FIT` | escala uniforme para **cobrir** os limites (pode cortar) |
| `STRETCH` | estica para preencher exatamente (ignora aspect ratio) |
| `FIT_WIDTH` / `FIT_HEIGHT` | ajusta à largura / à altura, mantendo proporção |
| `FIT_HALF_WIDTH` / `FIT_HALF_HEIGHT` | ajusta a metade da largura / altura |

``

## Exemplo completo (copiar, colar e rodar)
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.image.*;   // Image, ImageException

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // Carregar uma Image pode lançar ImageException/IOException — trate para não quebrar a tela.
      ImageView iv = new ImageView();          // vazio (placeholder: nada é desenhado)
      try {
         Image capa = new Image("cf/samples/api/ui/books/book1.png");
         iv.image(capa).imageSize(ImageSize.RATIO);
      } catch (ImageException e) {
         System.out.println("Imagem não encontrada, usando placeholder vazio: " + e.getMessage());
      }

      add(LAY_FILL, iv);
   }
}
```

> Os trechos abaixo mostram **só o miolo** (o que vai dentro de `onShow()`). Para rodar, coloque-os no esqueleto `MainWindow` acima.

## Uso básico
```java
Image capa = new Image("cf/samples/api/ui/books/book1.png");
ImageView iv = new ImageView(capa, ImageSize.RATIO);
container.add(LAY_FILL, iv);
```

## Construtores
| Construtor | Descrição |
|---|---|
| `ImageView()` | vazio (`image = null`, `ImageSize.RATIO`) |
| `ImageView(Image image)` | imagem com modo `RATIO` |
| `ImageView(Image image, ImageSize imageSize)` | imagem + modo de escala |

## Propriedades e personalização
| Propriedade / método | Tipo | Padrão | O que faz |
|---|---|---|---|
| `image(Image)` | `ImageView` (fluente) | `null` | troca a imagem (invalida cache/layout) |
| `imageSize(ImageSize)` | `ImageView` (fluente) | `RATIO` | define o modo de escala |
| `alignX(Position)` | `ImageView` (fluente) | `CENTER` | alinhamento horizontal (`START`/`CENTER`/`END`) |
| `alignY(Position)` | `ImageView` (fluente) | `CENTER` | alinhamento vertical |
| `getImage()` | `Image` | — | imagem atual (ou `null`) |
| `getImageSize()` | `ImageSize` | — | modo atual |
| `getAutoWidth()` / `getAutoHeight()` | `int` | — | tamanho da imagem + `ingap` (0 se sem imagem) |

## Callbacks e eventos
Nenhum. `ImageView` é não interativo.

## Estados
Sem estados de interação. Se `image == null`, nada é desenhado.

### Cover (recorte) com alinhamento ao topo
```java
Image foto = new Image(caminhoFoto);
ImageView avatar = new ImageView(foto, ImageSize.FIT)
   .alignY(Position.START);      // mantém o topo visível ao cortar
container.add(0.4f, avatar);
```

### Trocar a imagem em runtime (fluente)
```java
ImageView iv = new ImageView();          // vazio
container.add(LAY_FILL, iv);
// depois, ao carregar:
iv.image(new Image(novoCaminho))
  .imageSize(ImageSize.STRETCH);
```

## Boas práticas
- Dê ao `ImageView` um espaço de layout definido (`LAY_FILL` ou fração) — o modo de escala só faz sentido com limites conhecidos.
- Libere a `Image` com `dispose()` quando ela não for mais usada (recurso nativo — ver Cap. 18).
- No Web, prefira `ResizeQuality.FAST`; a escala interna do `ImageView` já usa esse caminho.

## Erros comuns
- **Confundir `FIT` com `RATIO`:** `RATIO` faz letter-box (cabe inteira); `FIT` cobre e pode cortar. `STRETCH` distorce.
- **Esperar tamanho automático de um `ImageView` sem imagem:** `getAutoWidth/Height()` retornam `0` quando `image == null`.

## Veja também
- Guia da área: [`ui/`](/docs/ui) · Receitas: [`cookbook/`](/docs/cookbook)
- Conceito (imagens, `Paint.image`): [`concepts/`](/docs/concepts)
- Componentes relacionados: [`Label`](/docs/ui/widgets/label) · [`Button`](/docs/ui/widgets/button)
