Reputation: 20244
I have a class which extends JPanel
. The size of the JPanel is set by adding the following method in the class:
@Override
public Dimension getPreferredSize() {
return new Dimension(WIDTH, HEIGHT);
}
the relevant fields of this class are:
int position = 0;
int randomSize = 0;
int randomPositionX = 0;
int randomPositionY = 0;
public final static int MAX_SIZE = 100;
public final static int MIN_SIZE = 10;
public final static int WIDTH = 500;
public final static int HEIGHT = 500;
private Random rand = new Random();
String alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
I choose a random size (Maximum of 100 and minimum of 10) and a random coordinate from a method. I also choose a random index for the string alphabets
:
randomSize = MIN_SIZE + (rand.nextInt(MAX_SIZE - MIN_SIZE) + 1);
randomPositionX = rand.nextInt(WIDTH - randomSize);
randomPositionY = rand.nextInt(HEIGHT - randomSize);
position = rand.nextInt(alphabets.length());
My attempt at drawing the letter and circle:
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillOval(randomPositionX, randomPositionY, randomSize, randomSize);
g.setFont(new Font("TimesRoman", Font.PLAIN, randomSize));
g.setColor(Color.RED);
g.drawString(alphabets.charAt(position) + "", randomPositionX + (randomSize/2), randomPositionY + (randomSize/2));
}
But it doesn't draw the letter at the center of the circle. In short, the problematic line is
g.drawString(alphabets.charAt(position) + "", randomPositionX + (randomSize/2), randomPositionY + (randomSize/2));
How do I achieve what I want?
MCVE as requested:
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Font;
import java.util.Random;
class MCVE{
static int randomSize = 0;
static int randomPositionX = 0;
static int randomPositionY = 0;
static int position = 0;
public final static int MAX_SIZE = 100;
public final static int MIN_SIZE = 10;
public final static int WIDTH = 500;
public final static int HEIGHT = 500;
private static Random rand = new Random();
static String alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static void main(String[] argv){
randomSize = MIN_SIZE + (rand.nextInt(MAX_SIZE - MIN_SIZE) + 1);
randomPositionX = rand.nextInt(WIDTH - randomSize);
randomPositionY = rand.nextInt(HEIGHT - randomSize);
position = rand.nextInt(alphabets.length());
JFrame frame = new JFrame("Test");
JPanel panel = new JPanel(){
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillOval(randomPositionX, randomPositionY, randomSize, randomSize);
g.setFont(new Font("TimesRoman", Font.PLAIN, randomSize));
g.setColor(Color.RED);
g.drawString(alphabets.charAt(position) + "", randomPositionX + (randomSize/2) - 15, randomPositionY + (randomSize/2) + 15);
}
};
frame.add(panel);
frame.setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Problem: The letter doesn't get drawn in the center of the circle.
Upvotes: 1
Views: 803
Reputation: 4052
Graphics drawString
draws the characters with the lower left corner of the text at the point specified. You will need to do some math in order to center them like you want.
First, we need to get the FontMetrics
from the Graphics
object we are using. Presumably, you will have already changed the font to the one you want.
FontMetrics metrics = g.getFontMetrics(g.getFont());
Now, we need to find the size of the text we will be drawing:
Rectangle2D bounds = metrics.getStringBounds(text, g);
Next, use these bounds to offset the text being drawn:
int offsetX = -bounds.getWidth()/2;
int offsetY = -bounds.getHeight()/2;
g.translate(offsetX, offsetY);
g.drawString(text, x, y);
g.translate(-offsetX, -offsetY);
Alternatively, bundle the offsets directly into the drawing call
int offsetX = -bounds.getWidth()/2;
int offsetY = -bounds.getHeight()/2;
g.drawString(text, x+offsetX, y+offsetY);
Upvotes: 1