Java GlassPanel clear transparent background - java

I want to render something on my GlassPane. The problem is, that if i move the rendered lines around, the previously rendered pixels have still the same color.
I can not use g.clearRect because it doesn`t clears the transparency.
Thats my rendering code:
Graphics2D g2 = (Graphics2D) g;
for(LinePath line : lines)
{
for(int i = 0; i < line.points.length; i+=2)
{
if(i != 0)
{
g.drawLine((int)line.points[i-2],(int)line.points[i-1],(int)line.points[i],(int)line.points[i+1]);
}
}
}
//Clearing alpha
Area area = new Area();
// This is the area that will filled...
area.add(new Area(new Rectangle2D.Float(0, 0, getWidth(), getHeight())));
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.0f));
g2.fill(area);
And here is the result:

clearRect should work but you have to reset your alpha composite before using it.
Ex:
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,1.0f));

Related

JButton background color AND image

I have read through and tried several approaches to changing the background color of a JButton with a buffered image, but I am consistently getting the same results. I am using a 2D array of ImageIcons, some with file names such as:
ImageIcon blackRook1 = new ImageIcon("ChessPiece/Chess_rdt60.png");
the png's I am using do not fill the entire square, just the actual chess piece
and others with BufferedImages such as:
ImageIcon space = new ImageIcon(new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB));
I am then looping through chessBoardSquares, which is an empty 8x8 2D array of JButtons, with:
Insets buttonMargin = new Insets(0, 0, 0, 0);
for(int i = 0; i < chessBoardSquares.length; i++) {
for(int j = 0; j < chessBoardSquares[i].length; j++) {
JButton b = new JButton();
b.setMargin(buttonMargin); // Insets object
ImageIcon icon = this.chessPieces[i][j]; // 2D array of ImageIcons
BufferedImage bi = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);[![enter image description here][1]][1]
Graphics2D g = bi.createGraphics();
//determine color of graphic and jbutton background
int colorDeterminator = j + i;
if(colorDeterminator % 2 == 0) {
// System.out.println("Getting here and coloring white");
b.setBackground(Color.WHITE);
g.setColor(Color.WHITE); // I have also tried with this line commented out
} else {
// System.out.println("Getting here and coloring black");
b.setBackground(Color.BLACK);
g.setColor(Color.BLACK);
}
g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
icon.paintIcon(null, g, 0, 0);
g.dispose();
b.setOpaque(true);
b.setIcon(icon);
the if statement using color determinator has definitely run as the print statements have executed
I cannot post images without enough reputation points, so my thought was to post the question in Game Development. I feel that it is more relevant to this channel however, so I will link to that post with the image here.
THE ISSUE
There is a square filling most of the JButton, which I believe is the BufferedImage, that is white regardless of what color I set the Graphics2D or the JButton itself. Because I want the whole square to be black in some cases (except for the piece on top of it), I need a way to color the rest of the square.
Same post with image

Why am I getting a black image after replacing all the pixels of a BufferedImage object with magenta colored ones?

I am following a Java Game development tutorial, and I hit a roadblock because I am unable to figure out what is wrong with my code. I am supposed to render a new image by changing each pixel of the buffered image into the color I want. Then I copy that array over to the array in my Game class and I draw the rendered image. The relevant code is directly below. I discuss what I have tried directly after the code snippets.
This code snippet is from my Game class:
private Screen screen;
private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// Converts image into array of integers
private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
public Game() {
Dimension size = new Dimension(width * scale, height * scale);
setPreferredSize(size);
screen = new Screen(width, height);
frame = new JFrame();
pixels = new int[width * height];
}
// Displays images to the screen
public void render() {
BufferStrategy bs = getBufferStrategy();
// Checks if the buffer strategy exists. If it doesn't create a triple buffer strategy
if(bs == null) {
// Triple buffering
createBufferStrategy(3);
return;
}
screen.render();
// Copies array in Screen class to pixels array in (this) class
for (int i = 0; i < pixels.length; i++) {
pixels[i] = screen.pixels[i];
}
// Must be in chronological order
Graphics g = bs.getDrawGraphics();
g.setColor(Color.CYAN);
g.fillRect(0, 0, getWidth(), getHeight());
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.dispose();
// Display next available buffer
bs.show();
}
This code snippet is from my Screen class:
private int width;
private int height;
public int[] pixels;
public Screen(int width, int height) {
this.width = width;
this.height = height;
// Size of the pixels array reserves one element for each pixel
pixels = new int[width * height];
}
public void render() {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
pixels[x + y * width] = 0xff00ff;
}
}
}
I have tried to "debug" by checking to see if both of my pixels arrays in the Game and the Screen class are being loaded with the magenta color. I simply did:
for (int i = 0; i < pixels.length; i++) {
pixels[i] = screen.pixels[i];
System.out.println(pixels[i]);
}
and I also tried:
for (int i = 0; i < pixels.length; i++) {
pixels[i] = screen.pixels[i];
System.out.println(screen.pixels[i]);
}
In both cases, the decimal representation of magenta (FF00FF in Hex) gets printed out until I close the window.
Another thing I tried is using the image.setRGBmethod to change the color of the image.
I added this line
image.setRGB(20, 20, 16711935); into the render method as follows:
// Displays images to the screen
public void render() {
BufferStrategy bs = getBufferStrategy();
// Checks if the buffer strategy exists. If it doesn't create a triple buffer strategy
if(bs == null) {
// Triple buffering
createBufferStrategy(3);
return;
}
screen.render();
// Copies array in Screen class to pixels array in Game (this) class
/* for (int i = 0; i < pixels.length; i++) {
pixels[i] = screen.pixels[i];
}
*/
// Must be in chronological order
Graphics g = bs.getDrawGraphics();
g.setColor(Color.CYAN);
g.fillRect(0, 0, getWidth(), getHeight());
image.setRGB(20, 20, 16711935);
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.dispose();
// Display next available buffer
bs.show();
}
A magenta dot showed up in my frame, and I am also able to turn the entire frame into a solid magenta color by modifying the render method in the Screen class. Now, I am wondering why my "original" code isn't working. From what I understand, the setRGB method is much slower than what I originally intended on using to render images, so I don't want to just give up and settle with using setRGB.
I have spent practically the entire day going over all the spelling in my code, making sure those nested for loops in the Screen class are correct, and etc. I am at a loss here. I don't understand what the issue is.
If the code snippets I included are not enough, I have created a Gist of my code in its entirety here.
This code gets the color int for the input rgb colors
public static int getIRGB(int Red, int Green, int Blue){
Red = (Red << 16) & 0x00FF0000; //Shift red 16-bits and mask out other stuff
Green = (Green << 8) & 0x0000FF00; //Shift Green 8-bits and mask out other stuff
Blue = Blue & 0x000000FF; //Mask out anything not blue.
return 0xFF000000 | Red | Green | Blue; //0xFF000000 for 100% Alpha. Bitwise OR everything together.
}
I suspect you are drawing a magenta color with 0% opacity

Adding multiple images to GPanel with Java

Im building a blackjack game in java for school and I can't seem to figure out how to add the first four cards to the GPanel. The array of cards are shuffled and the strings in the array match the file name of the images. I can get the first card in the array to load but not the other three. Any help would be awesome.
public void paintComponent(Graphics g) {
//System.out.println(gameInProgress);
if(gameInProgress == true) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Image image = null;
int i;
currentPosition = 0;
for (i = 0; i < 4; i++) {
image = Toolkit.getDefaultToolkit().getImage("images/"+deck[currentPosition - i]+".png");
currentPosition++;
}
g2.drawImage(image, 115, 5, 80, (int) 106.67, this);
g2.finalize();
}
}
You have 3 main issues in your code.
The first issue is caused by [currentPosition - i] because the result will always equal 0, so the image/card at array index 0 will be the only one that will ever be drawn.
The second issue is that you only draw one image because g2.drawImage is only called after the for loop, instead it should be inside the for loop so that all 4 images/cards are drawn.
The third issue is that you always draw your images in the same place, so even if you where drawing all 4 images you would only see the last one because it covers the previous ones.
Try this, it should print all 4 images (Assuming you have a 435x112 panel):
public void paintComponent(Graphics g) {
//System.out.println(gameInProgress);
if(gameInProgress == true) {
super.paintComponent(g);
//Add a couple new variables
int x = 115;
Graphics2D g2 = (Graphics2D) g;
Image image = null;
int i;
for (i = 0; i < 4; i++) {
image = Toolkit.getDefaultToolkit().getImage("images/"+deck[i]+".png");
//New location of g2.drawImage
//The X positions should change each time
g2.drawImage(image, x, 5, 80, 107, this);
//Change the X location of the next image
x = x + 80;
}
//Moved g2.drawImage from here to above the bracket
g2.finalize();
}
}

Disposing Graphics2D drawing after it is drawn

For a game that I'm working on I need to draw a rectangle that gets smaller and smaller. I have figured out how to draw the rectangle smaller by using a swing Timer like this:
timer = new Timer(100, new ActionListener(){
public void actionPerformed(ActionEvent e){
Graphics2D g2d = (Graphics2D) panel.getGraphics();
if(width > 64){
g2d.drawRect(x,y,width,height);
x += 1;
y += 1;
width -= 1;
height -= 1;
}
}
});
timer.start();
The problem I am having is that it wont remove the rectangle that was drawn before so it wont look like it's shrinking but more like it's filling in. So how would I remove the previously drawn rectangle right after the smaller rectangle have been drawn?
You might start with:-
Change:
Graphics2D g2d = (Graphics2D) panel.getGraphics();
to:
repaint();
The Graphics instance from getGraphics() is transient, the window might be repainted whenever the JVM feels it is necessary.
The overridden method might look like this.
#Override
public void paintComponent(Graphics g){
super.paintComponent(g); // Effectively clears the BG
Graphics2D g2d = (Graphics2D)g;
if(width > 64){
g2d.drawRect(x,y,width,height);
x += 1;
y += 1;
width -= 1;
height -= 1;
}
// Toolkit.getDefaultToolkit().sync();
// g2d.dispose(); NO! Don't dispose of this graphics instance
}

Drawing multiple lines in a BufferedImage

I am trying to draw horizontal and vertical lines on a bufferedimage. It should end up looking like a grid of cells. But when I run the code, I see only two lines: the leftmost line and the topmost line (ie. a line from 0,0 to 0,height of image & 0,0 to width of image,0) Heres the code snippet:
BufferedImage mazeImage = new BufferedImage(imgDim.width, imgDim.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = mazeImage.createGraphics();
g2d.setBackground(Color.WHITE);
g2d.fillRect(0, 0, imgDim.width, imgDim.height);
g2d.setColor(Color.BLACK);
BasicStroke bs = new BasicStroke(2);
g2d.setStroke(bs);
// draw the black vertical and horizontal lines
for(int i=0;i<21;i++){
g2d.drawLine((imgDim.width+2)*i, 0, (imgDim.width+2)*i, imgDim.height-1);
g2d.drawLine(0, (imgDim.height+2)*i, imgDim.width-1, (imgDim.height+2)*i);
}
And the overriden paint method:
public void paint(Graphics g) {
g.drawImage(mazeImage, 0, 0, this);
}
This is all in a class called RobotMaze that extends JPanel. Any help is appreciated.
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
class GridLines {
public static void main(String[] args) {
Dimension imgDim = new Dimension(200,200);
BufferedImage mazeImage = new BufferedImage(imgDim.width, imgDim.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = mazeImage.createGraphics();
g2d.setBackground(Color.WHITE);
g2d.fillRect(0, 0, imgDim.width, imgDim.height);
g2d.setColor(Color.BLACK);
BasicStroke bs = new BasicStroke(2);
g2d.setStroke(bs);
// draw the black vertical and horizontal lines
for(int i=0;i<21;i++){
// unless divided by some factor, these lines were being
// drawn outside the bound of the image..
g2d.drawLine((imgDim.width+2)/20*i, 0, (imgDim.width+2)/20*i,imgDim.height-1);
g2d.drawLine(0, (imgDim.height+2)/20*i, imgDim.width-1, (imgDim.height+2)/20*i);
}
ImageIcon ii = new ImageIcon(mazeImage);
JOptionPane.showMessageDialog(null, ii);
}
}
Print out your coordinates and you will see that you are plotting points outside the width and height of the image:
System.out.printf("Vertical: (%d,%d)->(%d,%d)\n",(imgDim.width+2)*i, 0, (imgDim.width+2)*i, imgDim.height-1);
System.out.printf("Horizontal: (%d,%d)->(%d,%d)\n",0, (imgDim.height+2)*i, imgDim.width-1, (imgDim.height+2)*i);
How do you expect the result of (imgDim.width+2)*i to be within the image boundaries if i > 0?

Categories

Resources