Java menubar hiding background image - java

Hi I'm following an online tutorial to make a rhythm game in Java and I have a problem with displaying the menubar. When I execute the program, the menubar seems to cover the background image and all I see is the menu bar on the top of the screen and a black screen below it. It seems like the code works on windows but it somehow doesn't work on a mac. Anybody know how to fix this problem?
package dynamic_beat_4;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class DynamicBeat extends JFrame {
private Image screenImage;
private Graphics screenGraphic;
private Image introBackground = new ImageIcon(Main.class.getResource("../images/introBackground.jpg")).getImage();
private JLabel menuBar = new JLabel(new ImageIcon(Main.class.getResource("../images/menuBar.png")));
public DynamicBeat() {
setUndecorated(true);
setTitle("Dynamic Beat");
setSize(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setBackground(new Color(0, 0, 0, 0));
setLayout(null);
menuBar.setBounds(0, 0, 1280, 30);
add(menuBar);
Music introMusic = new Music("intromusic.mp3", true);
introMusic.start();
}
public void paint(Graphics g) {
screenImage = createImage(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);
screenGraphic = screenImage.getGraphics();
screenDraw(screenGraphic);
g.drawImage(screenImage, 0, 0, null);
}
public void screenDraw(Graphics g) {
g.drawImage(introBackground, 0, 0, null);
paintComponents(g);
this.repaint();
}
}

Why do you call it a "menubar"? It is a JLabel. Swing has a specific component called a JMenuBar, so your terminology is very confusing trying to understand what you are really doing.
I see many inconsistencies:
You should NOT be overriding paint().
You should NOT be using a null layout, or setBounds().
You should NOT be invoking paintComponents() directly.
You should NOT be invoking repaint() in a method called from a painting method. Basically you are creating an infinite loop.
You should NOT be using getGraphics(). If you ever need to do custom painting then you just use the Graphics object passed to the painting method.
Not really sure what you are attempting to do but I would suggest that all you need to to use the defrault BorderLayout of the frame. Then the basic code is:
add(menuBar, BorderLayout.PAGE_START);
add(introBackground, BorderLayout.CENTER)
pack();
setVisible( true );
Read the section from the Swing tutorial on How to Use BorderLayout for more information and working examples to get you started.

Related

Java Background image not showing on Mac [duplicate]

This question already exists:
Java Graphics not showing on Mac even with overriding the paintComponent() method of the JPanel
Closed 2 years ago.
I'm new to Java and am trying to create a program in Swing following an Youtube Tutorial. Everything works fine in Windows but in Mac, the background image doesn't show up but only the menuBar(JLabel). I hope to get background image and JLabels in a same page.
Can someone please help me to continue in the right direction? I will put all the file codes so that understading the issue is better.
Thanks a lot in advance!
[Main.java]
package dynamic_beat_4;
public class Main {
public static final int SCREEN_WIDTH = 1280;
public static final int SCREEN_HEIGHT = 720;
public static void main(String[] args) {
new DynamicBeat();
}
}
[Dynamic Beat.java]
package dynamic_beat_4;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class DynamicBeat extends JFrame {
private Image screenImage;
private Graphics screenGraphic;
private Image introBackground = new ImageIcon(Main.class.getResource("../images/introBackground(Title).jpg"))
.getImage();
private JLabel menuBar = new JLabel(new ImageIcon(Main.class.getResource("../images/menuBar.png")));
public DynamicBeat() {
setUndecorated(true);
setTitle("Dynamic Beat Game");
setSize(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setBackground(new Color(0, 0, 0, 0));
setLayout(null);
menuBar.setBounds(0, 0, 1280, 30);
add(menuBar);
Music introMusic = new Music("introMusic.mp3", true);
introMusic.start();
}
public void paint(Graphics g) {
screenImage = createImage(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);
screenGraphic = screenImage.getGraphics();
screenDraw(screenGraphic);
g.drawImage(screenImage, 0, 0, null);
}
public void screenDraw(Graphics g) {
g.drawImage(introBackground, 0, 0, null);
paintComponents(g);
this.repaint();
}
}
Some major points.
don't call repaint inside of a paint method. This doesn't make sense.
the preferred painting technique of swing is to override paintComponent.
Don't override Window#paint and if you do, call super.paint(g). (As per the linked javadoc.)
Calling paintComponents(g) with the graphics object of a temporary image is unnecessary at best. Swing handles buffering.
I'm amazed this worked on any platform.
I think the easiest fix for this is to create a JPanel.
public DynamicBeat() {
setUndecorated(true);
setTitle("Dynamic Beat Game");
setSize(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setBackground(new Color(0, 0, 0, 0));
JPanel panel = new JPanel(){
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(introBackground, 0, 0, this);
}
};
panel.setLayout(null);
menuBar.setBounds(0, 0, 1280, 30);
panel.add(menuBar);
setContentPane(panel);
Music introMusic = new Music("introMusic.mp3", true);
introMusic.start();
}
You might want to refer to this painting in awt and swing.
Some further tips, don't extend JFrame, and do your GUI work on the EDT.

KeyListener in JPanel not working (panel is focused)

As the title says I'm trying to make add a keylistener to a JPanel. So far the only way I got it working was by adding an empty textfield and clicking on it. Now I don't want an empty textfield in my JPanel so I want to add the keylistener to the panel itself.
Here is the class I'm talking about:
package cookieClicker;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class CookieView extends JPanel
{
private CookieModel cm;
private ImageIcon cookie;
public Rectangle rect;
public CookieView(CookieModel cm)
{
this.cm = cm;
this.setFocusable(true);
this.requestFocusInWindow();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
cookie = new ImageIcon("Untitled-1.png");
g.setColor(Color.ORANGE);
g.drawImage(cookie.getImage(), this.getWidth() / 2 - 100, this.getHeight() / 2 - 100, 200, 200, this);
rect = new Rectangle(this.getWidth() / 2 - 100, this.getHeight() / 2 - 100, 200, 200);
}
public void addListener(MouseListener m, KeyListener k)
{
this.addMouseListener(m);
this.addKeyListener(k);
}
}
Does anyone know how to make this work?
panel is focused
How do you know the panel is focused?
The requestFocusInWindow() method only works when the frame is already visible at the time the method is invoked. So invoking the method in your constructor won't do anything.
The basic code should be:
CookieView panel = new CookieView();
JFrame frame = new JFrame();
frame.add(panel);
frame.pack();
frame.setVisible(true);
panel.requestFocusInWindow();
Also you should make sure all the code is execute on the Event Dispatch Thread.
However, you should probably not even be using a KeyListener. In most cases Swing was designed to be used with Key Bindings. Read the tutorial to see if key bindings will work for you.
Finally, you should NOT be reading an Image file in the paintComponent() method. The painting methods are called whenever Swing determines a component needs to be repainted so it is inefficient to keep reading the image over and over.

How do I make the JButtons all look the same when changing background color on some of them and not on others?

I have a JFrame that I am putting several JButtons on. Half the JButtons have color coding--i.e. I turn them blue when X event happens--and I use btn.setBackgroundColor(Color). When I use setBackgroundColor, I can see that I look the ones that are normal JButtons have shading/coloring/something that the ones with the setBackgroundColor do not. I've tried making the color transparent to a limited degree, but I still get a flat block of color, rather than a tinted version of the shaded button.
This seems like it should be a pretty easy thing to fix, but it is bugging me right now. I don't want to change the default LAF--it's fine. I don't want to abandon the color change. I do want the buttons to all appear styled (the word I'd use for HTML).
So I'm missing something right here....what is it?
Edited to add:
JFrame frame = new JFrame();
frame.add(new JButton("42"));
JButton btn24 = new JButton("24");
btn24.setBackground(Color.red);
frame.add(btn24);
frame.setVisible(true);
In the above example, "42" will--on my Windows machine--show a slight color variation at the bottom and the top, creating a rounded and shaded effect. The "24" button will show a red square. My question is: Is there a way to make "24" show the rounded/shaded/styled with the red tint on top? Or do I need to simple make all my buttons flat squares for a uniform appearance?
Thanks!
Create a custom JButton and override the paint method as illustrated bellow :
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
JButton btn24 = new DepthButton("24");
JButton btn25 = new DepthButton("25");
btn24.setBackground(Color.red);
btn25.setBackground(Color.GREEN);
JPanel pane = new JPanel(new BorderLayout());
pane.add(new JButton("42"), BorderLayout.PAGE_START);
pane.add(btn24, BorderLayout.PAGE_END);
pane.add(btn25, BorderLayout.CENTER);
frame.add(pane);
frame.pack();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
}
/**
*
* #author Romain Guy
*/
public static class DepthButton extends JButton {
/** Creates a new instance of DepthButton */
public DepthButton(String text) {
super(text);
setContentAreaFilled(false);
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
GradientPaint p;
p = new GradientPaint(0, 0, new Color(0xFFFFFF), 0, getHeight(), getBackground());
Paint oldPaint = g2.getPaint();
g2.setPaint(p);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.setPaint(oldPaint);
super.paintComponent(g);
}
}
}
And Here is the Result:
The example is from an excellent book for advanced java swing : Filthy Rich Clients
https://github.com/romainguy/filthy-rich-clients/blob/master/Gradients/TwoStopsGradient/src/DepthButton.java

Re-position and change buttons to images?

I am trying to re-position the button so that it is in the bottom right corner of the frame, but everything I try such as setLocation and setBounds, don't seem to do anything. Also, how would I change the button to an image? So that it is still a button, but an image is displayed.
package TrainCounselor;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Start extends JPanel {
public Start() {
// Game Properties
setOpaque(false);
setLayout(new FlowLayout());
}
public void paint(Graphics g) {
Image a = Toolkit
.getDefaultToolkit()
.getImage(
"C:/Users/Mel/workspace/camptycoon/javagame/src/javagame/background1.png");
g.drawImage(a, 0, 0, this);
super.paint(g);
}
public static void main(String[] args) {
JFrame myFrame = new JFrame("Put Image");
JButton startButton = new JButton("Start");
startButton.setLayout(null);
startButton.setLocation(50, 50);
Start c = new Start();
c.add(startButton);
myFrame.add(c);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setTitle("Counselor Training");
myFrame.setSize(755, 600);
myFrame.setResizable(false);
myFrame.setVisible(true);
}
}
I am trying to re-position the button so that it is in the bottom right corner of the frame
Use the appropriate Layout Managers.
I would start by using a JPanel with a FlowLayout that is right aligned. Then you add this panel to the "SOUTH" of the BoderLayout which is used by the JFrame.
See A Visual Guide to Layout Managers for more information.
Note when you add the Start class to the frame you are adding it to the "CENTER", not the south. Also, custom painting is done by override the paintComponent() method, not the paint() method and don't forget to invoke super.paintComponent() before you draw the image, not after.
Also, how would I change the button to an image? So that it is still a button, but an image is displayed.
Read the section from the Swing tutorial on How to Use Buttons.

Transparent JPanel over Canvas (VLCJ)

I know that a similar question was posted before, but there was no answer or example code.
I need a transparent JPanel on top of a canvas. The code posted below is not working
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
public class Main {
private static class Background extends Canvas{
#Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.RED);
g.drawOval(10, 10, 20, 20);
}
}
private static class Transparent extends JPanel {
public Transparent() {
setOpaque(false);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GREEN);
g.drawOval(20, 20, 20, 20);
}
}
public static void main(String[] args){
JFrame frame = new JFrame();
JLayeredPane layered = new JLayeredPane();
Background b = new Background();
Transparent t = new Transparent();
layered.setSize(200, 200);
b.setSize(200, 200);
t.setSize(200, 200);
layered.setLayout(new BorderLayout());
layered.add(b, BorderLayout.CENTER, 1);
layered.add(t, BorderLayout.CENTER, 0);
frame.setLayout(new BorderLayout());
frame.add(layered, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setVisible(true);
}
}
Using the GlassPane property of the entire frame is the very last solution (highly discouraged)
You probably will not be able to get this to work because you are mixing heavyweight and lightweight components together.
In the past it used to be impossible to draw lightweight panels over heavyweight components like a Canvas. Since JDK 6 Update 12 and JDK 7 build 19 Java has corrected this and you can overlap the 2 correctly however it comes with limitations. Specifically in your case the Overlapping swing component cannot be transparent.
A good description for this including the newer behaviour can be found on this page: Mixing Heavyweight and Lightweight Components Check the limitations section for your specific problem.
I don't think using the GlassPane will help as it is also lightweight.
If you change the BackGround class to extend JPanel instead of Canvas you will get the behaviour you want.
While AWT is limited it should not be too hard to implement something similar with AWT itself by extending either the Container or Component class.

Categories

Resources