Now I feel like I've been looking all over the internet to find out how to add a border on a text, so I decided to ask here, since you guys always knows the answer.
So, how do I, in java, draw a border of approx 2 pixels around every letter in a string drawn on a Graphics2D element ?
Like this:
Thanks in advance.
I found one simple solution in Javaworld for drawing an outline on text in Java:
g.setColor(Color.red);
g.drawString("Outline", ShiftWest(x, 1), ShiftNorth(y, 1));
g.drawString("Outline", ShiftWest(x, 1), ShiftSouth(y, 1));
g.drawString("Outline", ShiftEast(x, 1), ShiftNorth(y, 1));
g.drawString("Outline", ShiftEast(x, 1), ShiftSouth(y, 1));
g.setColor(Color.yellow);
g.drawString("Outline", x, y);
Essentially, you draw the same string shifted in each direction first before you draw the string in the desired color. This works well for a one pixel outline, but does not scale well to thick outlines as there may be gaps in the corners if you repeat the shifting multiple times.
Another solution would be to use a transformation and getOutline() which is a method of the TextLayout class. An example for doing outline can be found here.
See: Transforming Shapes, Text, and Images. Set the "primitive" to "text" and the "rendering" to "Stroke and Fill" in the transform example.
Related
I'm coding a collision system for my 2D game engine in Java but I'm having problems with obtaining certain values. Lets say I have a rectangle and want to inscribe it into a grid. I want to list every grid cell which collide with the rectangle. As of rectangle what I know is its width, height, center point (x, y), angle in radians. As of cell, the coordinates of each cell are basically (n * size, m * size) where n, m = -2, -1, 0, 1, 2... (like in the image). I've been trying to find a fast solution for a long time but with no luck. I have also created a reference image for you to better understand my problem. The pink cells are the ones I want. I hope there's someone who had a similar problem and is willing to help me out :) Best of luck in your projects.
I need an information: I have to do a project for my university's stage. My program allow me to discover an image with circular movement. I have a lot of images that should be collect in a unique "long" image, with black edges. Is it possible?
I searched in the other topic but they are only for iOs or html. My application is an application in java that will be use on the pc.
Sorry for the bad english
Thank's, Elia.
Using the dogbane's answer,
You could adapt the code easily to do what you want.
Using Graphics.fillRect to create a rectangle. Just need to set the color to black but you will need to manage the height and width in code.
g.setColor(Color.BLACK);
//Black rectangle on the left edge
g.fillRect(x, y, rectWidth, rectHeight);
x += rectSize;
for(String image : images){
BufferedImage bi = ImageIO.read(new File(image));
g.drawImage(bi, x, y, null);
x += bi.getWidth();
//Black rectangle on the right
g.fillRect(x, y, rectWidth, rectHeight);
x += rectSize;
}
You will see an rectWidth, rectHeight to generate the black square. You have two solutions here,
set it yourself (a parameter that you give from the batch)
iterate on the image first to get the biggest height of this batch (carefull on the perfs)
Note :
to improve this, you might want to center the image if those have some different sizes ... this will requires somt update to add a black square up above and below. But it's a nice exercice ;)
The default background is black, so you don't need to create the filled rectangle for a black one (default byte are 0 so black #000000)
Stangely, a Windows XP tell me the PNG is not valid but on a Seven it works fine, might need to investigate this.
UPDATE :
Since we need the result image height and width on the beginning (didn't though about it), we answer some question
It is easy to update the background color to don't bother with it later (paint the full image at the beginning
We are force to iterate the image first to do the sum of there width
We can get the maximum height in the same time
Java student here
I'm trying to create a line that moves as I move a physical accelerometer/gyro, and a method that returns TRUE when the line intersects with rectangles I've positioned in a 2D coordinate system.
Obviously Line2D and Rectangle2D are graphical classes which I've just discovered won't work unless it's set in a JFrame and painted, which I'm not looking for. So I was wondering if there were other classes that might be better suited for this. Or do I have to manually always calculate the equation of the line segment, and four sides of a rectangle segment and check for intersections that way?
Any ideas?
The classes just encapsulate shape information. You can use them perfectly fine without rendering and even in a "headless" (no rendering hardware) environment.
Line2D line = new Line2D.Double(1, 5, 4, 0);
Rectangle2D rect = new Rectangle2D.Double(1, 1, 2, 2);
System.out.println(line.intersects(rect));
This outputs "true".
I have the following code:
private _x,_y,_w,_h;
protected void paintComponent( Graphics g_ ) {
g_.setStroke( new BasicStroke(2) );
g_.drawLine(_x, _y, _x+_w, _y+_h);
g_.drawLine(_x, _y+_h, _x+_w, _y);
}
In my case I'm drawing the diagonals of a square so: _w==_h.
My problem the two line don't have the same apparent thikness: the first line look thicker than the second. When checking the actual pixels drawn here's the difference of rendering:
I don't really care which one should be considered "correct" (though I'd like to understand the reasons of this result), but I'd like some coherence here, that both lines have the same rendering: how can I do that?
(when I use a 1px stroke, there's no difference between the two lines).
Followup to Olavi's ansewer:
Using an odd number of pixel for the stroke doesn't solve the problem:
Enabling anti-aliasing leads to another problem: the stroke of the square in which the cross is drawn gets blurred:
Basically you have two options:
Use an odd-number thickness
Use antialiasing
Personally I prefer antialiasing, because it's pretty and I like pretty things. However to explain why a stroke width of 2 behaves like that: Java does not know whether or not draw the line with the first way or the second way (I can't really explain exactly why it does what it does, but this is what I see). To further elaborate this answer, try starting the other line one pixel to the left or to the right: this should result in two lines with the same thickness.
To use antialiasing, do the following (untested code!). Code picked up from here:
Graphics2D graphics2D = (Graphics2D) g_;
graphics2D.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.drawLine(_x, _y, _x+_w, _y+_h);
graphics2D.drawLine(_x, _y+_h, _x+_w, _y);
When you use Graphics2D.scale(); and draw a shape, the outline thickness is also scaled.
Is there a way to draw it without the line thickness being scaled? Perhaps there's another efficient way to scale it other than using the above function?
This question is similar. It looks like you have to mess around with a Stroke object to set the right line width.
You're going to have to save your drawing as a list of line vectors, and scale and render the drawing at various sizes to maintain the line thickness you want.
I've just found a solution to my own question. I've no idea how efficient it is but it works as intended:
Area area = new Area(myShape); //myShape is the shape I want to scale
AffineTransform at = new AffineTransform();
at.scale(2,2);
area = area.createTransformedArea(at);
graphics2d.draw(area); //graphics2d is the Graphics2D instance to do the drawing
Perhaps someone could enlighten me as to whether or not this is a good approach to take?