本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。
自定义绘制(onPaint)
当没有任何 widget 合适时,创建一个 Component 并重写 onPaint(Paint paint)。坐标是
局部的(0,0 = 左上角;width/height 是组件的尺寸)。
完整示例(复制、粘贴并运行)
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
/** 可执行的主界面。将 launcher 指向此类(classname)并运行:gradlew :lwjgl3:run */
public class MainWindow extends Window
{
/** 自定义组件:绘制一个"徽章"(带数字的彩色药丸)。 */
static class Badge extends Component
{
private int valor;
Badge(int valor) { this.valor = valor; }
@Override
public void onPaint(Paint paint) throws Exception
{
// 本地坐标:(0,0) = 左上角;width/height = 组件尺寸。
GRect r = new GRect()
.bounds(0, 0, width, height)
.fill(0xFFE53935) // 红色 ARGB
.radius(height / 2); // 药丸 / 圆形
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); // 居中的白色文本
}
}
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
Badge badge = new Badge(7);
add(LAY_AUTO, badge); // 将自定义组件添加到屏幕
}
}
下面的片段只展示了核心部分(放入
onShow()内部的内容)。要运行它们,请将其放入上面的MainWindow骨架中。
骨架
public class Badge extends Component {
private int valor;
public Badge(int valor) { this.valor = valor; }
@Override public void onPaint(Paint paint) throws Exception {
// 填充的圆形背景
GRect r = new GRect()
.bounds(0, 0, width, height)
.fill(0xFFE53935) // 红色
.radius(height / 2); // 药丸形/圆形
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);
}
}
// 修改“值”后重绘:repaint();
Paint 的绘图原语
| 调用 | 绘制 |
|---|---|
paint.rect(GRect r) |
矩形(填充/边框/圆角/阴影)— 配置 GRect |
paint.text(String, x, y, color, Font) |
文本 |
paint.line(x1, y1, x2, y2, color, thick) |
线条 |
paint.image(Image, x, y[, w, h]) |
图像 |
paint.polyline(GLines) / paint.polygon(GLines) |
折线 / 多边形 |
GRect — 可配置的矩形
流式:.bounds(x,y,w,h) · .fill(color) · .border(color, thick) · .radius(r) /
.radius(tl,tr,br,bl)。然后 paint.rect(gr)。
GRect card = new GRect().bounds(0, 0, width, height)
.fill(0xFFFFFFFF).border(0xFFE0E0E0, 1).radius(8);
paint.rect(card);
最佳实践
- 绘制时相对于
width/height(而非固定值)— 保持响应式。 - 复用
GRect/Font对象(作为字段),而不是每帧分配。 - 当影响绘制的状态改变时,调用
repaint()(渲染是按需的)。
常见错误
- 在
onPaint中使用屏幕的绝对坐标 — 它们是相对于组件的局部坐标。 - 改变被绘制的数据后忘记
repaint()。 - 将颜色作为对象传递 — 颜色是
intARGB(Color类不存在)。
另请参阅
- 图像 · Whiteboard · 颜色
这个页面有帮助吗?感谢你的反馈!