I need to achieve the effect of "lights off" while displaying animation. It's currently been done with transparent Jframe, black background with 50% opacity the size of the monitor. then, there is this canvas component which should draw RGBA buffered-image.
Problems pops up when the the JFrame opacity effects the Canvas as well, making it semi transparent. That's what i'm trying to avoid.
//** Window class extends Canvas
public Window(){
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
int hostMonitorWidth = gd.getDisplayMode().getWidth();
int hostMonitorHeight = gd.getDisplayMode().getHeight();
Dimension dimension = new Dimension(hostMonitorWidth, hostMonitorHeight);
super.setPreferredSize(dimension);
window = new JFrame();
window.setUndecorated(true);
window.setOpacity(0.55f);
window.setLayout(new GridLayout());
window.setSize(hostMonitorWidth, hostMonitorHeight);
window.add(this);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLocationRelativeTo(null);
window.setVisible(true);
window.requestFocus();
window.setFocusableWindowState(true);
super.createBufferStrategy(3);
}
public void draw(){
BufferStrategy buffer = super.getBufferStrategy();
java.awt.Graphics g = buffer.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0,0, super.getWidth(), super.getHeight());
g.drawImage(batch.getImage(), 0, 0, super.getWidth(), super.getHeight(), null);
g.dispose();
buffer.show();
}
I have tried couple combinations of the following code with Jpanel, Layered Panes, Jlabel and what not. It's always seems to keep the opacity / throwing unexplainable exceptions / not working for any reason.
Am i doing it the correct way? what am i missing here?
Don't use setOpacity, use setBackground on the JFrame and pass it a alpha based color. This will allow the frame to become transparent without affecting the other components.
You may, however, find that Canvas doesn't like alpha based colors (as it only has an opaque state)
Related
This question already has answers here:
Can not draw oval on a JPanel
(2 answers)
Closed 2 years ago.
I'm trying to add a circle to my JPanel, but it won't draw the cricle.
the code below creates a JFrame, creates a JPanle and calls a function to add a circle to the JPanel(pgame), but it doesn't actually add it.
Help appreciated
fgame = new JFrame("Backgammon");
fgame.setSize(1000, 1000);
pgame = new JPanel();
pgame.setPreferredSize(new Dimension(1000, 687));
pgame.setLayout(new GridLayout(3, 10));
pgame.setBorder(BorderFactory.createEmptyBorder(309,460,150,460));
Circle Circlepanel = new Circle();
pgame.add(Circlepanel);
Circlepanel.setVisible(true);
fgame.add(pgame,BorderLayout.CENTER);
fgame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fgame.setTitle("Backgammon");
fgame.pack();
fgame.setVisible(true);
public class Circle extends JPanel {
public void paint(Graphics g) {
g.drawOval(500, 500, 100, 100);
g.setColor(Color.RED);
g.fillOval(500, 500, 100, 100);
}
}
First of all variable names should NOT start with an upper case character. Most of you names are correct, but not all. Learn Java conventions and be consistent!
Your create a GridLayout
pgame.setLayout(new GridLayout(3, 10));
Which will attempt to allocate space for 3 components vertically in the frame.
Then you create a Border:
pgame.setBorder(BorderFactory.createEmptyBorder(309,460,150,460));
which will give your component a height of 459 and a width of 920.
Finally you try to draw the oval at (500, 500) from the top left of the panel.
g.drawOval(500, 500, 100, 100);
Well, the problem is that you have weird random numbers and the size of your component isn't large enough to paint the oval in the space of the component.
To demonstrate this add and retest:
Circlepanel.setBackground( Color.YELLOW );
You will see a yellow panel. Next change:
//pgame.setLayout(new GridLayout(3, 10));
pgame.setLayout(new GridLayout(1, 0));
and you will see a taller yellow panel in the middle of the frame because you are only allocating space for a single component.
Next change:
//pgame.setBorder(BorderFactory.createEmptyBorder(309,460,150,460));
pgame.setBorder(BorderFactory.createEmptyBorder(50,50,50,50));
and you will see part of the oval because you have reserved less space for the border.
Next change:
//g.fillOval(500, 500, 100, 100);
g.fillOval(0, 0, 100, 100);
and you will see the oval at the top of the panel.
The point is that specifying the:
grid size
border size
oval location
all affect the size of the component and how it is painted.
Other issues:
override the getPreferredSize() method of your Circle class to return the desired size of the panel
custom painting is done by overriding paintComponent(), not paint();
you need to invoke super.paintComponent(..) at the start of the method.
Read the section from the Swing tutorial on Custom Painting for more information and working examples.
I'm building a simple 2D game in Java.
I'm using the JFrame class, but I don't think the width and height are what I specified, or perhaps the graphics are incorrect.
Here are some snippets of my code:
public final static int WIDTH = 600, HEIGHT = 900;
JFrame frame = new JFrame();
frame.setSize(WIDTH, HEIGHT);
g.setColor(Color.BLACK);
g.fillRect(0, 0, WIDTH, HEIGHT - 10);
The JFrame is displaying a black background. However, based on the arguments I gave to the fillRect function, there should still be a 10px tall sliver of white at the bottom of the frame. This is not the case. The white sliver only really starts to show after a 30px decrease from the height of the frame.
Thanks for your help.
The JFrame size includes the borders so you need to allow for them. To facilitate dealing with this don't specify the width and height of the JFrame. I recommend doing the following.
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(width,height));
frame.add(panel);
// add other components in the panel
frame.pack();
// center on screen.
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Now your panel will be the specified size.
Note, if your going to paint, make certain you override paintComponent(Graphics g) in JPanel and do your painting there.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// your code here
}
I just converted my project from RGB to ARGB. The opaque objects all draw fine but when I add transparency to the 'color' (set by hex: 0x55ff0000) of any drawn object they only draw the correct transparency if they are moving.
The problem: Alpha drawn objects seem to 'stack' up every step until they are opaque.
While they remain stationary they quickly become more and more opaque over a second. I'm still learning how the BufferedImages work but I believe i'm missing a piece of code that I require for ARGB instead of just RGB.
public class Window
{
private JFrame frame;
static BufferedImage image;
private Canvas canvas;
private BufferStrategy bs;
private Graphics g;
public Window(Game game)
{
image = new BufferedImage(game.getWidth(), game.getHeight(), BufferedImage.TYPE_INT_ARGB);
canvas = new Canvas();
Dimension s = new Dimension(game.getWidth() * game.getScale(),game.getHeight() * game.getScale());
canvas.setPreferredSize(s);
canvas.setMaximumSize(s);
canvas.setMinimumSize(s);
frame = new JFrame(game.getName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(canvas, BorderLayout.CENTER); //Add canvas to the frame
frame.pack(); //Set frame to size of canvas
//Removed some other 'frame.xxx' lines of code which don't assist the problem.
//frame.repaint();
canvas.createBufferStrategy(2);
bs = canvas.getBufferStrategy();
g = bs.getDrawGraphics();
}
public void update()
{
g.drawImage(image, 0, 0, canvas.getWidth(), canvas.getHeight(), null); //Draws everything to buffer strategy.
bs.show(); //Draws from buffer strategy to canvas.
}
public JFrame getFrame()
{
return frame;
}
}
The only other code I changed to convert to ARGB was this which was 0 beforehand:
public Renderer(Game game)
{
display = ((DataBufferInt)game.getWindow().getImage().getRaster().getDataBuffer()).getData(); //Displays all the data drawn to screen.
}
public void clear()
{
for(int i = 0; i < display.length; i++) //Loops through the screens pixels and clears them.
{
display[i] = 0xff000000; //Clear the screen with opaque black.
}
}
When I change display[i] = 0xff000000; to 0x0f000000 the problem is exacerbated and it has a slow motion effect - but i'm not sure how to increase an already full alpha of "ff" higher.
I make a GIF of the problem, however it's distorted a fair bit: https://giphy.com/gifs/java-RF6stHznOiR9e
Note how it fades back in after I stop moving, and where the circle overlaps it stays opaque.
I'm not well familiar with Java and try to build a grid in a window but I'm not sure which Class I should extend (like JFrame) and which method is the best way to get that grid.
My goal is to create a grid and let the squares blink randomly.
I tried it JPanel but not sure if it is the right way
JPanel content = new JPanel(new GridLayout(4,4));
I would use a JPanel on a JFrame. You override the paintComponent Method of the JPanel to fit your needs:
#Override
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
//draw rects
for(int i=0; i<n; i++){
//draw rects
g2d.drawRect(x, y, width, height);
}
//fill rects
for(int i=0; i<n i++){
//set random color for blinking effect
g2d.setColor(/*random color*/);
g2d.fillRect(x, y, width, height);
}
}
You have to compute the grid yourself though, using the size of your JPanel and the size of the squares you want to draw.
Then, set a Timer and redraw every time you want that blinking effect.
If you are not familiar with java Swing and simple draw operations, you should watch same tutorials etc. because im not going to explain it all here ;).
I have an image that is too tall for my JFrame even when it is maximized. I want to dynamically resize it so that the image will never be clipped by the top or bottom of the JFrame. I have inserted the image within a JLabel as an ImageIcon. I have tried setting the maximum size to no avail. How do I ensure that the height of the image will never be larger than the JFrame? I would ideally like to keep the ratio of height to width constant. The image is in a portrait orientation. Any ideas?
public class myClass extends JFrame {
private void initGUI(){
pane = getContentPane();
pane.setLayout(new BorderLayout());
next = new JButton("Next");
previous = new JButton("Previous");
page = new JLabel(loadImg());
page.setMaximumSize(this.getSize());
pane.add(next, BorderLayout.EAST);
pane.add(previous, BorderLayout.WEST);
pane.add(page, BorderLayout.CENTER);
}
}
I would ideally like to keep the ratio of height to width constant.
Check out Darryl's Stretch Icon. It will shrink/grow depending on the space available, while maintaining the width/height ratio.
You can try overriding the paintComponent(Graphics g) method and drawing the resized image yourself.
page = new JLabel(loadIMG()){
#Override
paintComponent(Graphics g)
{
//So we don't kill default behaviour
super.paintComponent(g);
int scaledWidth, scaledHeight;
//pseudo-code
scale and store into scaledWidth and scaledHeight;
render with g.drawImage(icon, x, y, scaledWidth, scaledHeight, null);
}
};