Kỹ thuật: Override paintComponent + Graphics2D.rotate()
JLabel không có built-in rotation. Cách làm: tạo subclass JLabel, override paintComponent(Graphics g), ép Graphics sang Graphics2D, gọi rotate(theta, x, y) rồi gọi super.paintComponent(g).
Ví dụ: Xoay chữ "TutorialsPoint" 0.6 radian (~34°) quanh tâm label
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class RotateJLabelDemo extends JFrame {
public RotateJLabelDemo() {
setTitle("Rotate JLabel Demo");
JLabel label = new RotateLabel("TutorialsPoint");
add(label, BorderLayout.CENTER);
setSize(400, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
private class RotateLabel extends JLabel {
public RotateLabel(String text) {
super(text);
Font font = new Font("Verdana", Font.ITALIC, 20); // to hơn để dễ thấy
setFont(font);
// Tính bounds để label đủ lớn chứa text xoay
FontMetrics fm = getFontMetrics(font);
java.awt.geom.Rectangle2D bounds = fm.getStringBounds(text, null);
setSize((int) bounds.getWidth() + 20, (int) bounds.getHeight() + 20);
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create(); // tạo copy để không ảnh hưởng gốc
// Xoay quanh tâm component
g2d.rotate(0.6, getWidth() / 2.0, getHeight() / 2.0);
super.paintComponent(g2d);
g2d.dispose(); // giải phóng resource
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(RotateJLabelDemo::new);
}
}
Kết quả

Lưu ý: Nên dùng g.create() và dispose() để tránh làm hỏng graphics context gốc. Tính toán size thích hợp để text không bị cắt.