Ich hatte mal eine Roulettescheibe gezeichnet, … es ist nicht genau das gleiche, geht aber so sehr in diese Richtung, dass ich es deswegen (und aus Prinzip) mal von “der anderen Seite” hier rüber rette:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
class RouletteDrawTest
{
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final RoulettePanel p = new RoulettePanel();
Thread thread = new Thread(new Runnable()
{
public void run()
{
double angle = 0;
while (true)
{
p.setRotationAngle(angle);
angle += 0.02;
try
{
Thread.sleep(20);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
return;
}
}
}
});
thread.start();
f.getContentPane().add(p);
f.setSize(600,600);
f.setVisible(true);
}
});
}
}
class RoulettePanel extends JPanel
{
private static final int numbers[] = new int[]
{
0,32,15,19, 4,21, 2,25,17,34, 6,27,
13,36,11,30, 8,23,10, 5,24,16,33, 1,
20,14,31, 9,22,18,29, 7,28,12,35, 3,
26
};
private double rotationAngleRad = 0.0;
private Dimension currentSize = null;
private Font currentFont = null;
private Path2D currentSegment = null;
public void setRotationAngle(double angleRad)
{
this.rotationAngleRad = angleRad;
repaint();
}
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
double currentAngleRad = rotationAngleRad;
int w = getWidth();
int h = getHeight();
Dimension size = getSize();
g.setColor(Color.WHITE);
g.fillRect(0,0,w,h);
//g.setRenderingHint(
// RenderingHints.KEY_ANTIALIASING,
// RenderingHints.VALUE_ANTIALIAS_ON);
int offsetX = 20;
int offsetY = 20;
int diameter = Math.min(w-2*offsetX,h-2*offsetY);
int radius = diameter/2;
int centerX = offsetX+radius;
int centerY = offsetY+radius;
if (!size.equals(currentSize))
{
int fontSize = (int)(radius * 0.1);
currentFont = new Font("Serif", Font.BOLD, fontSize);
}
g.setFont(currentFont);
double angleRadDelta = Math.PI * 2 / numbers.length;
if (!size.equals(currentSize))
{
FontMetrics fontMetrics = g.getFontMetrics();
int fontHeight = fontMetrics.getHeight();
currentSegment = createSegment(
centerX, centerY, radius-fontHeight,
radius, -angleRadDelta/2, angleRadDelta/2);
}
FontRenderContext fontRenderContext =
new FontRenderContext(null, true, true);
for (int i=0; i<numbers.length; i++)
{
double angleRad = currentAngleRad + i * angleRadDelta;
if (i==0)
{
g.setColor(new Color(0,192,0));
}
else if ((i&1)==1)
{
g.setColor(Color.RED);
}
else
{
g.setColor(Color.DARK_GRAY);
}
AffineTransform rotationAT =
AffineTransform.getRotateInstance(angleRad, centerX, centerY);
g.fill(rotationAT.createTransformedShape(currentSegment));
g.setColor(Color.WHITE);
String numberString = String.valueOf(numbers**);
GlyphVector glyphVector = currentFont.createGlyphVector(
fontRenderContext, numberString);
Shape textShape = glyphVector.getOutline();
AffineTransform textAT = new AffineTransform(rotationAT);
Rectangle2D sBounds = currentSegment.getBounds2D();
Rectangle2D tBounds = textShape.getBounds2D();
double dx = sBounds.getCenterX() - tBounds.getCenterX();
double dy = sBounds.getCenterY() - tBounds.getCenterY();
textAT.concatenate(AffineTransform.getTranslateInstance(dx, dy));
g.fill(textAT.createTransformedShape(textShape));
}
}
private static Path2D createSegment(
int centerX, int centerY, int innerRadius, int outerRadius,
double angleRad0, double angleRad1)
{
Arc2D.Double arcInner = new Arc2D.Double(
centerX-innerRadius, centerY-innerRadius,
innerRadius*2, innerRadius*2,
Math.toDegrees(angleRad0),
Math.toDegrees(angleRad1-angleRad0), Arc2D.OPEN);
Arc2D.Double arcOuter = new Arc2D.Double(
centerX-outerRadius, centerY-outerRadius,
outerRadius*2, outerRadius*2,
Math.toDegrees(angleRad1),
Math.toDegrees(angleRad0-angleRad1), Arc2D.OPEN);
Path2D.Double path = new Path2D.Double();
path.append(arcInner, true);
path.append(arcOuter, true);
path.closePath();
AffineTransform at = AffineTransform.getRotateInstance(
-Math.PI/2, centerX, centerY);
path.transform(at);
return path;
}
}
Vielleicht hilft’s ja schon. Für weitere Aspekte der Spinner-Funktionalität (also alles, was über das reine Zeichnen hinausgeht) müßte man die Anforderungen noch genauer eingenzen und spezifizieren.
EDIT: Falls es darum geht, wirklich den TEXT “gebogen” zu schreiben, wie einen Halbkreis oben…
L
A L
H O
… müßte man sich was anderes überlegen - meintest du sowas? (Da liegt auch schon ewig ein angefangenes Programm dafür auf meinem Desktop, aber da müßte noch etwas Arbeit reingesteckt werden…)