I am wanting to turn the example below in a figure that uses RoundedRectangles instead of normal rectangles, I know there are possibilities with the clipping frame.
But I don't really know how they would apply to my current situation, as I am not using a g2d.fillXXX() function currently.
The image:
example http://img827.imageshack.us/img827/6048/cardbackgroundcut.jpg
The code:
private void createImage() {
bufferedImage = new BufferedImage(dimension.width, dimension.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D)bufferedImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
int colorRed = 128;
int colorGreen = 0;
int colorBlue = 128;
for (int x = 0; x < dimension.width; x++) {
for (int y = 0; y < dimension.height; y++) {
int dx = Math.min(x, dimension.width - x);
int dy = Math.min(y, dimension.height - y);
if (dx < 10 || dy < 10) {
g2d.setColor(new Color(colorRed, colorGreen, colorBlue, 255 - Math.min(dx, dy)));
g2d.drawLine(x, y, x, y);
}
else {
g2d.setColor(new Color(colorRed, colorGreen, colorBlue, 192 - Math.min(dx, dy)));
g2d.drawLine(x, y, x, y);
}
}
}
}
So basically I would want both the outer edge and the inner edge of the image have a rounded rectangle, while preversing the changes in color.
Any clues how to accomplish this?
Regards.
you can use a RoundRectangle and 4 (turned) rectangles
cast all the shape to Area's to and use the
area.exclusiveOr(ohterArea)
method to get the 4 separate (different gradient) parts.
And then draw these parts 1 by 1 using the GradientPaint class to paint (fill) all these 4 parts to the desired gradient.
and as a last step you set the paint back to a static color and you draw the old RoundedRectangle (so you get the edge)
Related
I'm new to Java as well as user interfaces, and I have a problem with Java Graphics. What I'm trying to achieve is drawing a grid on a JPanel, and then paint custom components into the grid.
Here is the class I want to draw the grid on (its base extends JPanel).
public class RectGridPanel extends GridPanel
{
List<Rectangle> rects;
public RectGridPanel(Simulator sim)
{
super(sim);
this.rects = new ArrayList<Rectangle>();
this.setLayout(new GridLayout(20,20));
for(int x = 1; x < 801; x += 40)
{
for(int y = 2; y < 801; y += 40)
{
Cell newCell = new RectCell(x, y, sim);
this.add(newCell);
}
}
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.BLACK);
for(int x = 1; x < 801; x += 40)
{
for(int y = 2; y < 801; y += 40)
{
Rectangle rect = new Rectangle(x, y, 40, 40);
g2.draw(rect);
rects.add(rect);
}
}
}
}
Here are the cells I want to draw inside the grid:
public class RectCell extends Cell
{
Rectangle shape;
public RectCell(int x, int y, Simulator sim)
{
super(x, y, sim);
shape = new Rectangle(x, y, CELL_SIZE, CELL_SIZE);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.BLACK);
g2.fill(shape);
}
}
So the grid on its own draws out fine, but as soon as I try to create cells inside it it gets disrupted like that:
public class RectCell extends Cell
{
Rectangle shape;
public RectCell(int x, int y, Simulator sim)
{
super(x, y, sim);
shape = new Rectangle(x, y, CELL_SIZE, CELL_SIZE);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.BLACK);
g2.fill(shape);
}
}
The Graphics object that is passed to this paintComponent() function defines the screen space where the current RectCell can draw. The coordinate sysetem is relative to the upper left corner of the RectCell, so drawing the background should always start at x = 0 and y = 0 or some other meaningful value. The coordinates here are not relative to the parent component as you seem to assume.
Better yet, set the background color and let Swing take care of painting it rather than painting a rectangle yourself.
It is not clear what you try to achive.
What is the reason for RectCell? Why not paint the shapes direct in the RectGridPanel?
The nested loop in the paintComponent it not a good idea. Be aware that the paintComponent is called very often and every time you in crease the rects list with new objects. The former painted rectangles get lost (qraphicaly) and new rectangles with the same parameters are blowing the list.
I'm new at Java and I'm trying to make a chess with it for training.
I'm having some trouble with the Graphic methods though.
I listed the functions which the mistake could have been in.
The code below shows a function called in main.
This function is inside my package that handle Graphic stuff.
public class GUI_main extends JComponent{
private final int tam = 100;
private final int tamTab = 8 * tam;
Image torre;
public void inicializaTabuleiro(Torre t)
{ //Sets the window properties and the "tile" proper image.
JFrame janela = new JFrame("Xadrez");
janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
janela.setSize(816, 839);
janela.getContentPane().add(new GUI_main());
janela.setLocationRelativeTo(null);
janela.setResizable(false);
janela.setVisible(true);
paintPeca(t); /*this one is the function that sets the correct image
for the tile that will be on the board*/
System.out.println("Janela inicializada com sucesso!");
}
...
next one is the "paintPeca" function, which should initialize "Image torre".
public void paintPeca(Torre t)
{
System.out.println(t.imgPeca());
torre = Toolkit.getDefaultToolkit().getImage(t.imgPeca());
}
and finally my paint function:
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.black);
int x = 0, y = 0;
while(y<tamTab) //draw board
{
if(y%200 == 0)
{
g2.draw(new Rectangle2D.Double(x, y, tam, tam));
x = x + tam;
g2.fill(new Rectangle2D.Double(x, y, tam, tam));
x = x + tam;
}
else
{
g2.fill(new Rectangle2D.Double(x, y, tam, tam));
x = x + tam;
g2.draw(new Rectangle2D.Double(x, y, tam, tam));
x = x + tam;
}
if(x == tamTab)
{
y = y + tam;
x = 0;
}
}
x = 14;
y = 19;
g2.drawImage(torre, x, y, this); //draw tower
g2.finalize();
...
Together these functions should have draw a board and a tower on it.
It's showing me the board, but not the tower (Image torre), and I do not have a clue on the reason.
"t.imgPeca()" returns a string (path to image), and it's correct, as I have tested before.
Since I'm new at Java this might be some kind of of silly mistake, but I have not found the answer in other pages of stack that talked about the drawImage function.
I have a BufferedImage and I am trying to fill a rectangle with transparent pixels. The problem is, instead of replacing the original pixels, the transparent pixels just go on top and do nothing. How can I get rid of the original pixel completely? The code works fine for any other opaque colors.
public static BufferedImage[] slice(BufferedImage img, int slices) {
BufferedImage[] ret = new BufferedImage[slices];
for (int i = 0; i < slices; i++) {
ret[i] = copyImage(img);
Graphics2D g2d = ret[i].createGraphics();
g2d.setColor(new Color(255, 255, 255, 0));
for(int j = i; j < img.getHeight(); j += slices)
g2d.fill(new Rectangle(0, j, img.getWidth(), slices - 1));
g2d.dispose();
}
return ret;
}
public static BufferedImage copyImage(BufferedImage source){
BufferedImage b = new BufferedImage(source.getWidth(), source.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = b.getGraphics();
g.drawImage(source, 0, 0, null);
g.dispose();
return b;
}
Using AlphaComposite, you have at least two options:
Either, use AlphaComposite.CLEAR as suggested, and just fill a rectangle in any color, and the result will be a completely transparent rectangle:
Graphics2D g = ...;
g.setComposite(AlphaComposite.Clear);
g.fillRect(x, y, w, h);
Or, you can use AlphaComposite.SRC, and paint in a transparent (or semi-transparent if you like) color. This will replace whatever color/transparency that is at the destination, and the result will be a rectangle with exactly the color specified:
Graphics2D g = ...;
g.setComposite(AlphaComposite.Src);
g.setColor(new Color(0x00000000, true);
g.fillRect(x, y, w, h);
The first approach is probably faster and easier if you want to just erase what is at the destination. The second is more flexible, as it allows replacing areas with semi-transparency or even gradients or other images.
PS: (As Josh says in the linked answer) Don't forget to reset the composite after you're done, to the default AlphaComposite.SrcOver, if you plan to do more painting using the same Graphics2D object.
I am wondering how to rotate things I have already drawn (like lines) in Java drawing Panel (not in JPanel).
I am trying to rotate a triangle i created by connecting 3 lines:
g.drawLine(size, size, 2*size, size);
g.drawLine(size, size,size+size/2, size+(int)(size/2 * Math.sqrt(3)));
g.drawLine(2*size, size,size+size/2, size+(int)(size/2 * Math.sqrt(3)));
How do I rotate that?
If you want to rotate a point like that, then you could:
double startX; // <------------|
double startY; // <------------|
double endX; // <------------|
double endY; // <-define these
double angle; // the angle of rotation in degrees
To draw the original line
g.setColor(Color.BLACK);
g.drawLine(startX, startY, endX, endY); //this is the original line
double length = Math.pow(Math.pow(startX-endX,2)+Math.pow(startY-endY,2),0.5);
double xChange = length * cos(Math.toRadians(angle));
double yChange = length * sin(Math.toRadians(angle));
To draw the new, rotated line
g.setColor(Color.GRAY);
g.fillRect(0,0,1000,1000); //paint over it
g.setColor(Color.BLACK);
g.drawLine(startX, startY, endX + xChange, endY + yChange);
Use graphics2D and Polygons
Graphics2D g2 = (Graphics2D) g;
int x2Points[] = {0, 100, 0, 100}; //these are the X coordinates
int y2Points[] = {0, 50, 50, 0}; //these are the Y coordinates
GeneralPath polyline =
new GeneralPath(GeneralPath.WIND_EVEN_ODD, x2Points.length);
polyline.moveTo (x2Points[0], y2Points[0]);
for (int index = 1; index < x2Points.length; index++) {
polyline.lineTo(x2Points[index], y2Points[index]);
};
g2.draw(polyline);
If you want to rotate it, just do it over but add, before
g2.rotate(Math.toRadians(angle), centerX, centerY);
Where "angle" is the amount you want to rotate it and (centerX, centerY) are the coordinates of the point you want to rotate it around.
I hope this helps
I am drawing a solid blue line on a JPanel via
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
super.paint(g2);
if (path.size() >= 2) {
BasisStroke stroke = new BasicStroke(Config.TILE_SIZE_IN_PIXEL / 3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
g2.setStroke(stroke);
g2.setPaint(Color.BLUE);
g2.setPaintMode();
for (int i = 0; i < path.size() - 1; i++) {
g2.drawLine(path.get(i).x, path.get(i).y, path.get(i + 1).x, path.get(i + 1).y);
}
}
}
Yet I want this line to be semi-transparent. How do I achieve that?
The short answer is to set the alpha for the color of your graphic context:
float alpha = 0.5;
Color color = new Color(1, 0, 0, alpha); //Red
g2.setPaint(color);
Alpha ranges between 0.0f (invisible) to 1.0f (opaque)
For the long answer with examples, see this article.