How do I add JLabels over the Graphics class - java

I created a test class for my pong game to be able to add JLabels on my JFrame. However when I used the graphics class, the JLabel does not show up and I can't fix the problem.
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Main extends JFrame {
JLabel label;
public Main() {
JPanel p = new JPanel();
p.setLayout(null);
label = new JLabel("Text inside");
label.setBounds(1100, 500, 200, 50);
p.add(label);
add(p);
setSize(1700, 712);
setTitle("Title");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public void paint(Graphics g) {
g.setColor(Color.green);
g.fillRect(0, 0, 1700, 712);
g.setColor(Color.DARK_GRAY);
g.drawRect(1050, 450, 300, 200);
}
public static void main(String[] args) {
new Main();
}
}

The JavaDoc for Window.paint() clearly states:
If this method is reimplemented, super.paint(g) should be called so that lightweight components are properly rendered.
You don't do this, so your lightweight components (i.e. your JLabels) are no longer rendered.

Related

Java Graphics not showing on Mac even with overriding the paintComponent() method of the JPanel

I'm working on a small game project and am having an issue with java graphics not being displayed. I've searched similar questions here on Stackoverflow and used overriding the paintComponent() method of the JPanel which many ppl advised but am still having this issue. I hope to get my background image and menubar, and music at the same time. Music works fine but background image and menubar doesn't show up at all.
here's my code :
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
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() {
menuBar.setBounds(0, 0, 1280, 30);
add(menuBar);
Music introMusic = new Music("introMusic.mp3", true);
introMusic.start();
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);
add(new DynamicBeatPane());
pack();
}
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);
this.repaint();
}
public static class DynamicBeatPane extends JPanel {
#Override
protected void paintComponent(Graphics g) {
// Call the superclass paint method.
super.paintComponent(g);
}
}
}

Repaint() does not work after adding more components to JPanel in Swing, Java

I am starting with Java and want to make a simple pong game to get into the ways of displaying stuff in java. I have created 2 classes that both extend JPanel and call the repaint() function every 16.6 milliseconds. I added both to a JPanel which I added to the frame, but only the component I added first displays.
I've tried to revalidate() after repaint() in both classes and made sure that the Timer actually works and that it's actionPerformed() method is actually called.
This is the main method:
public class Main {
public static void main(String[] args){
JFrame frame = new JFrame("Pong");
//...
JPanel mainPanel = new JPanel();
mainPanel.add(new Player());
mainPanel.add(new Ball(frameWidth/2, frameHeight/2 -40));
frame.add(mainPanel);
}
}
This is the important code for the classes (It's basically the same for both of them):
public class Player extends JPanel {
public Player(){
setPreferredSize(new Dimension(Main.frameWidth, Main.frameHeight));
setBackground(Color.BLACK);
new Timer(1000/60, new ActionListener(){
public void actionPerformed(ActionEvent e){
update();
repaint();
}
}).start();
}
//...
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
}
}
(Of coure I left things like #Override or unneseccary functions out to shorten the code)
This code only paints the Player, altough I want it to display all the components of mainPanel.
This is an example that you can (hopefully) run. I had to split it up into 3 files, since I suck at anonymus classes:
Main.java
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args){
JFrame frame = new JFrame("Pong");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 800);
JPanel mainPanel = new JPanel();
mainPanel.add(new Player());
mainPanel.add(new Ball());
frame.add(mainPanel);
frame.setVisible(true);
}
}
///////
Player.java
//////
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Player extends JPanel{
private int x = 20, y = 300, width = 20, height = 100;
public Player(){
setPreferredSize(new Dimension(800, 800));
setBackground(Color.BLACK);
new Timer(1000/60, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
repaint();
}
}).start();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
}
}
//////
Ball.java
//////
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Ball extends JPanel{
private int x = 20, y = 300, width = 20, height = 100;
public Ball(){
setPreferredSize(new Dimension(800, 800));
setBackground(Color.BLACK);
new Timer(1000/60, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
repaint();
}
}).start();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
}
}
In method paintComponent() of class Player, you paint the exact same Rectangle each time. In order to achieve animation, each time you paint the rectangle you need to change either its size or location or both. What do you expect the Player to do? Should it move up and down along the left edge of the window? Have you seen the lesson entitled How to Use Swing Timers which is part of Oracle's Java Tutorial?
EDIT
I see now that Player hides Ball, because of the default layout manager of JPanel. The below code is essentially the code you posted but I set GridLayout as the layout manager for mainPanel. Also, a java source code file may contain more than one class but exactly one class must be public. Hence in the below code only class Main is public.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Pong");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel(new GridLayout(0, 2));
mainPanel.add(new Player());
mainPanel.add(new Ball());
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
class Player extends JPanel {
public Player() {
setBorder(BorderFactory.createLineBorder(Color.RED, 2, false));
setPreferredSize(new Dimension(800, 800));
setBackground(Color.BLACK);
new Timer(1000 / 60, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}).start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(20, 100, 20, 100);
}
}
class Ball extends JPanel {
public Ball() {
setBorder(BorderFactory.createLineBorder(Color.CYAN, 2, false));
setPreferredSize(new Dimension(800, 800));
setBackground(Color.BLACK);
new Timer(1000 / 60, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}).start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(300, 300, 10, 10);
}
}
And here is a screen capture of the GUI...
I just realized that if I extend my window manually, the second JPanel shows up under the one responsible for the Player! This means that I'll need to set the Panels position somehow, right?
#Abra

JButtons Only Working When Mouse Hovers Over

I am a beginner in Java and programming overall, and I started by making a simple JFrame with a few buttons. Now when I created the buttons, the only way they would appear is if I hovered over them with my mouse.
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JFrame {
public Main() {
setTitle("Test");
setSize(600, 500);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new FlowLayout());
JPanel p = new JPanel();
JButton b = new JButton("Derp");
p.add(b);
add(b);
setVisible(true);
revalidate();
repaint();
}
public static void main(String[] args) {
new Main();
}
public void paint(Graphics g) {
g.drawString("Under Construction...", 240, 250);
}
}
Help would be appreciated, also please note I do not know that much about Java and I don't know a descent amount of the languages. Also, a way to make the buttons have the Aero texture instead of the default one would be nice :)
Since you override paint you need to call super.paint(g); as the first line.
public void paint(Graphics g) {
super.paint(g); // <-- add this.
g.drawString("Under Construction...", 240, 250);
}
Also, you should move your logic off the main() thread; like
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Main();
}
});

Why is graphics not showing on my JFrame / JPanel?

When I run this code. The result is a window with the name. Fully blank. I tried editing background color and adding graphics (rectangle) etc but the same result keeps occurring .
Question: This ends up as a white screen on a window. No graphics or background color. Even though I added it to panel and added panel. How do I fix this?
Main.java
package ball.tec.main;
import javax.swing.JFrame;
import ball.tec.frame.Frame;
public class Main {
public static void main(String[] args) {
String Version = "0.1.2";
Frame f = new Frame();
f.setVisible(true);
f.add();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.setSize(1500, 1000);
f.setTitle("RedBall V: " + Version);
}
}
Frame.java
package ball.tec.frame;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Frame extends JFrame{
private static final long serialVersionUID = 1L;
public boolean debug = false;
//Creating panel object
JPanel panel = new JPanel();
//Graphics displayed
public void paintComponent(Graphics g) {
//Firstly Nothing pops up
g.setColor(Color.RED);
g.drawRect(20, 40, 10, 10);
//And this doesn't work.
this.setBackground(Color.RED);
}
//Add everything to 'panel'
public void add() {
add(panel);
//Even if I put it here it doesn't work ;-;
this.setBackground(Color.RED);
this.pack();
}
}
You don't use paintComponent() in a JFrame. What you probably intended to do was create a third class, extending JPanel. Add your paintComponent() there.
public class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.drawRect(20, 40, 10, 10);
this.setBackground(Color.RED);
}
}
f.add(new MyPanel());

How to make a JPanel inside a JFrame fill the whole window?

In the below example, how can I get the JPanel to take up all of the JFrame? I set the preferred size to 800x420 but it only actually fills 792x391.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BSTest extends JFrame {
BufferStrategy bs;
DrawPanel panel = new DrawPanel();
public BSTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout()); // edited line
setVisible(true);
setSize(800,420);
setLocationRelativeTo(null);
setIgnoreRepaint(true);
createBufferStrategy(2);
bs = getBufferStrategy();
panel.setIgnoreRepaint(true);
panel.setPreferredSize(new Dimension(800,420));
add(panel, BorderLayout.CENTER); // edited line
panel.drawStuff();
}
public class DrawPanel extends JPanel {
public void drawStuff() {
while(true) {
try {
Graphics2D g = (Graphics2D)bs.getDrawGraphics();
g.setColor(Color.BLACK);
System.out.println("W:"+getSize().width+", H:"+getSize().height);
g.fillRect(0,0,getSize().width,getSize().height);
bs.show();
g.dispose();
Thread.sleep(20);
} catch (Exception e) { System.exit(0); }
}
}
}
public static void main(String[] args) {
BSTest bst = new BSTest();
}
}
If you are having only one panel in frame and nothing else then try this:
Set BorderLayout in frame.
Add panel in frame with BorderLayout.CENTER
May be this is happening because of while loop in JPanel.(Not sure why? finding actual reason. Will update when find it.) If you replace it with paintComponent(g) method all works fine:
public BSTest() {
//--- your code as it is
add(panel, BorderLayout.CENTER);
//-- removed panel.drawStuff();
}
public class DrawPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
System.out.println("W:" + getSize().width + ", H:" + getSize().height);
g2d.fillRect(0, 0, getSize().width, getSize().height);
}
}
//your code as it is.
Here's an alternative using pack instead.
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PackExample extends JFrame {
public PackExample(){
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(800,600));
panel.setBackground(Color.green);
add(panel);
pack();
setVisible(true);
}
public static void main(String[] args){
new PackExample();
}
}
This took me forever to figure out but its actually the simplest code ever.
Just create a parent panel and pass GridLayout then add your child panel like this.
JPanel parentPanel= new JPanel(new GridLyout());
JPanel childPanel= new JPanel();
parentPanel.add(childPanel);
If you want to fill the JFrame with the whole of JPanel you need to setUndecorated to true i.e. frame.setUndecorated(true);. But now you have to worry about your MAXIMIZE< MINIMIZE, and CLOSE Buttons, towards the top right side(Windows Operating System)

Categories