I have this problem in practice, the frame does not display the image I have in the folder image, someone can tell me why? i add the hierarchy of the project
package frame;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Frame {
Frame() {
final JFrame login = new JFrame();
login.setTitle("Title");
login.setLayout(null);
login.add(new JLabel(new ImageIcon("Images/images.png")));
login.setVisible(true);
login.setSize(500, 400);
login.setLocationRelativeTo(null);
}
public static void main(String[] args) {
new Frame();
}
}
Avoid setLayout (null), if you do not have sound reason for it. Remove the below code. Image will get displayed.
If you still have to use a null layout, you have to set the width and height of the component, along with its its x and y position.
login.setLayout(null);
For getting resources from project use URL instead of String path. For example:
URL resource = Frame.class.getResource("/Images/images.png");
ImageIcon icon = new ImageIcon(resource);
JLabel lbl = new JLabel(icon);
Also read that.
Also don't use null LayoutManager, in that case you need to specify bounds of component with help of setBounds() method.
Don't use a package for resources. Instead, create a non-source folder called "images", and move it there.
After that, use that path "images/images.png"
Related
How do I make a JLabel text vertically and horizontally aligned to the center?
I have to make use of setHorizontalTextPosition and setVerticalTextPosition. Can this be achieved by using these 2?
I have tried but the text remains at the top itself.
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
public class label extends JFrame
{
private JLabel label;
public label() //constructor
{
super("Simple GUI");
setLayout(new FlowLayout());
label=new JLabel("Centered JLabel");
label.setHorizontalTextPosition(SwingConstants.CENTER);
label.setVerticalTextPosition(SwingConstants.CENTER);
add(label);
}
}
I have tried but the text remains at the top itself.
You have two problems:
Andrew addressed the first problem. You are using the wrong method.
Next you are using the wrong layout. The FlowLayout only display components on a single line so the component will always be at the top. Don't change the layout manager. The default layout manager for a JFrame is the BorderLayout. When you add a component to the CENTER (which is the default when you don't specify a constraint), the component will be sized to fill the entire frame. Then the "alignment" properties will control the position of the text within the size allocated to the label.
Or a different option is to use a GridBagLayout. Then you don't need to play with alignment options of the component:
setLayout( new GridBagLayout() );
add(label, new GridBagConstraints());
Try both options as both may be effective in different situations.
Read the Swing tutorial on Layout Managers to better understand how each layout manager works.
I'm very sorry to don't know why the setHorizontalTextPosition method and the setVerticalTextPosition method doesn't work.
But, I'll let you know that there're several ways to sort the text in the label by inserting parameters an alignment with String when we create the label.
First of all, camickr's answer is the best answer, Because Swing was designed to be used with layout managers!!
Please remember that the most recommended method is to apply GridBagLayout() to the Layout of JFrame by camickr.
This answer is intended to inform you that
This method is also possible, but not recommended in the normal case
Using this method is not recommended because changing the size of the frame
keeps the components in place, but it could give you a little help
when it is indicated that the size and location of components in the
container are used in a way that can be used in special cases, such as
when they need to be fixed without external impact.
To get a better idea of the problem, I'll simply change the code that you uploaded to me so that it can be executed.
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import java.awt.Color;
public class StackOver extends JFrame
{
private JLabel label;
public StackOver() //constructor
{
super("Simple GUI");
setLayout(null);
setSize(500,300);
label=new JLabel("Centered JLabel", JLabel.CENTER);
/*
label.setHorizontalTextPosition(SwingConstants.CENTER);
label.setVerticalTextPosition(SwingConstants.CENTER);*/
add(label);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new StackOver();
}
}
Hmm, let's put some color in JLabel's background to find out more.
label.setOpaque(true); //Transparency Settings
label.setBackground(Color.pink); //Specify background color
//to use 'Color' class, We must import java.awt.Color;
the JFrame setting was set to FlowLayout()which makes the location and size of components were fixed, so we couldn't see it working!
So now we're going to go through the next two processes.
1) Changing JFrame's layout to null to use Absolute Layout ("not recommended, just a case")
2) Changing the size and location of the JLabel
after the progress we can see that the text alignment works!
1) Changing JFrame's Layout
the following link: Layout Manager shows that there are so many Layouts outside of FlowLayout.
Swing is designed to use the layout manager, so of course you should use one of the Layout above link.
But, to use an interesting way that fix the location and size of components absolutely We will switch to setLayout(null);!
2) Changing the size and location of the JLabel
We can directly change the size and position of JLabel with setBounds(int startX, int startY, int Width, int Height) method!
import java.awt.FlowLayout;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import java.awt.Color;
public class StackOver extends JFrame
{
private JLabel label;
public StackOver() //constructor
{
super("Simple GUI");
setLayout(null);
setSize(500,300);
label=new JLabel("Centered JLabel", JLabel.CENTER);
// Since it also sets the size of the JLabel,
//let's use the constructor to set the alignment of the text inside the JLabel.
label.setOpaque(true); //Transparency Settings
label.setBackground(Color.pink); //Specify background color
//to use 'Color' class, We must import java.awt.Color;
Rectangle r = this.getBounds(); //to get Frame Size
label.setBounds(r.x+100, r.y+100, r.width-200, r.height-200);
/*
label.setHorizontalTextPosition(SwingConstants.CENTER);
label.setVerticalTextPosition(SwingConstants.CENTER);*/
add(label);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new StackOver();
}
}
Now we can see the text of JLabel in the middle as intended!
This method can directly fix the size and location of all components (ex buttons), but the location and size of the components are fixed even if the window size of the JFrame changes after the program runs.
so If you really want set components Absolutely by this way, you rather to set JFrame Resizable false by adding below code on JFrame's code
this.setResizable(false);
I hope the answer was helpful to you and have a peaceful day!
Modifiers.java:
package game;
import java.awt.*;
import java.io.*;
import javax.swing.*;
public class Modifiers extends Data{
public static void setupJcomponents(){
frame.setUndecorated(true);
frame.setSize(MW,MH);
frame.setResizable(false);
frame.setVisible(true);
frame.setLayout(null);
for(int btn=0; btn<4; btn++) {
Buttons[btn] = new JPanel();
Buttons[btn].setBounds(btn*100,0,100,100);
Buttons[btn].setVisible(true);
Buttons[btn].setBackground(new Color(btn*50,btn*50,btn*50));
frame.getContentPane().add(Buttons[btn]);
}
menuBackground.setBounds(0,0,MW,MH);
menuBackground.setVisible(true);
menuBackground.setBackground(Color.black);
healthIndicator.setText(String.valueOf(healthValue));
healthIndicator.setFont(new Font("Terminal", Font.PLAIN, 100));
healthIndicator.setBounds(600,600,100,100);
healthIndicator.setForeground(Color.blue);
try{
PixelFont = Font.createFont(Font.TRUETYPE_FONT, new File("PixelFont.ttf"));
} catch (IOException e) {
PixelFont = new Font("Terminal", Font.PLAIN, 100);
} catch(FontFormatException e) {
PixelFont = new Font("Terminal", Font.PLAIN, 100);
}
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(PixelFont);
frame.getContentPane().add(healthIndicator);
frame.getContentPane().add(menuBackground);
}
}
Data.java:
package game;
import java.awt.*;
import javax.swing.*;
public class Data {
// this is where I will declare and alter all variable that will be used
public static JFrame frame = new JFrame();
public static JLabel healthIndicator = new JLabel();
public static JPanel Buttons[] = new JPanel[5];
public static JPanel menuBackground = new JPanel();
public static final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
public static final int MW = (int) screenSize.getWidth();
public static final int MH = (int) screenSize.getHeight();
public static Font PixelFont;
public static int maxHealth = 100;
public static int healthValue = maxHealth;
}
Frame.java:
package game;
public class Frame {
public static void main(String[] args) {
Modifiers.setupJcomponents();
}
}
whenever i rum Frame.java the menu Background disappears and the text altogether stops showing up. but if the path to the .ttf file is wrong it just skips over the font and uses the default instead. How do i get this font to load properly as well as not cause my background background to disappear? I have tried changing the path to the .ttf file and turning various parts of the code into comments, but even if the font of the health indicator is a default font, these errors will still occur, however if i try removing the try-catch loop then the errors aren't there anymore.
There are all kinds of problems with the code. Not exactly sure why the Fonts is causing an issue, but it has something to do with the overall structure of your code and you aren't using Swing the way it was designed to be used.
whenever i rum Frame.java the menu Background disappears and the text altogether stops showing up
What appears to be directly related to the above question is that the setVisible(true) statement should be executed AFTER all the components have been added to the frame. This will make sure all the components are painted.
Note this will still only work by chance because you happen to add the "background" panel to the frame last. Swing paints components in the reverse order that are added to any given panel.
Regarding other problems.
your painting code only works by chance. You should not be adding all your components directly to the frame. Swing is not designed to paint components in 3 dimensions directly when the components overlap one another. Swing is designed to have a parent child relationship. So that would mean you add your "background" panel to the frame. Then you add a panel containing the buttons to the "background" and you add the "health" component to the background.
Related to above you should NOT be using a null layout. Swing was designed to be used with a layout manager. This will make sure components don't overlap. So in your case you can use a BorderLayout for the "background" panel. Then you can add the "buttons" panel to the BorderLayout.PAGE_Start and the "health" component to the `BorderLayout.PAGE_END. This will ensure that the components are at the top/bottom of the background panel.
Don't set the size of the frame. Instead you use the setExtendedState(JFrame.MAXIMIZED_BOTH) property. The frame will be the size of the screen. The "GamePanel" will be take up all the space of the frame. So there is no need to set or use hardcoded values.
Don't use static variables and method. This indicates poor design. What you should be doing is creating a GamePanel class, which would essentially be your background panel. This class would contain the instance variables needed for the game. It would create the "buttons" panel and the "health" component and add it to itself.
Variable names should NOT start with upper case characters.
I'm trying yo write a java app with a JFrame object that must show three label objects, with text and image, my text "North" and "South" shows up on execution, but my image does not, even I put the image file into src folder.
package deitel9;
import java.awt.BorderLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JFrame;
public class LabelDemo {
public static void main(String[] args)
{
//crate a label with a plain text
JLabel northLabel = new JLabel("North");
//crate an icon from an image so we can put it on a JLabel
ImageIcon labelIcon = new ImageIcon("maldive.jpg");
//crate a label with an Icon instead of text
JLabel centerLabel = new JLabel(labelIcon);
//create another label with an Icon
JLabel southLabel = new JLabel(labelIcon);
//set the label to display text (as well as an icon)
southLabel.setText("South");
//create a frame to hold the labels
JFrame application = new JFrame();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//add the labels to the frame; the second argument specifies
//where on the frame to add the label
application.add(northLabel,BorderLayout.NORTH);
application.add(centerLabel,BorderLayout.CENTER);
application.add(southLabel,BorderLayout.SOUTH);
application.setSize(300,300);
application.setVisible(true);
}//end main
}//end class LabelDemo
Since your image stored in same package where LabelDemo is stored, try this,
ImageIcon labelIcon = new ImageIcon(LabelDemo.class.getResource("/deitel9/maldive.jpg").getFile());
or
private String getImage() {
return getClass().getResource("/deitel9/maldive.jpg").getFile();
}
ImageIcon labelIcon = new ImageIcon(new LabelDemo().getImage());
To figure out what you did wrong in a situation like this, you can simply call
File file = new File ("maldive.jpg");
System.out.println(file.getAbsolutePath());
This will print out the absolute path it is looking at for your file, which might give you an indication about what you did wrong.
Of course if you know how to use the debugger, you don't need the second line (and technically not even the first one, but that's a bit trickier ;))
According to the documentation, the ImageIcon constructor you chose expects a file name or file path, thus the image needs to be on file system rather than on the class path.
Creates an ImageIcon from the specified file. [...] The specified String can be a file name or a file path.
Given your description, when your project layout looks like this
\---src
\---deitel9
LabelDemo.java
maldive.jpg
then you should be able to retrieve the image as resource located on the class path like this:
ImageIcon labelIcon = new ImageIcon(LabelDemo.class.getResource("maldive.jpg"));
Well basically I tried to display a .gif using a url but it's given me a null pointer exception and I'm not really sure why since my url is correct and there's no other problems with my code(At least none that I can see).
import javax.swing.*;
import java.net.*;
public class image {
public image() {
}
public static void main(String[] args) {
URL url = image.class.getResource("<http://cdn.osxdaily.com/wp-content/uploads/2013/07/dancing-banana.gif>");
ImageIcon imageIcon = new ImageIcon(url);
JLabel label = new JLabel(imageIcon);
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.add(label);
frame.add(panel);
frame.setTitle("Title");
frame.setSize(700,500);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
URL url = image.class.getResource("<http://cdn.osxdaily.com/wp-content/uploads/2013/07/dancing-banana.gif>");
is not how you reference an image from a web resources. You would use this method to load resources that are embedded within your application (within the context of the applications classpath)
URL url = new URL("http://cdn.osxdaily.com/wp-content/uploads/2013/07/dancing-banana.gif");
would probably work better...
Remember, that downloading and loading the image may take some time, you may want to use a MediaTracker to track the progress, this would allow you to provide feedback to the user and know when to update the screen with the image once it's available, for example.
Before anyone asks, I choose not to use ImageIO to load an animated gif, because that is just a lot more work (as demonstrated here - not for the faint hearted). In this case, the MediaTracker could be used to check for errors
I have added the image in the src and bin directories and cross-checked that the name of the image file is correct
Here is the main class
import javax.swing.*;
public class apples
{
public static void main(String args[])
{
JFrame frame = new JFrame();
MyDrawPanel wid = new MyDrawPanel();
frame.add(wid);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(300,300);
}
}
and here is the class that does the image adding part
import java.awt.*;
import javax.swing.*;
public class MyDrawPanel extends JPanel
{
public void paintComponent(Graphics g)
{
Image image = new ImageIcon("b.png").getImage();
g.drawImage(image,20, 20, this);
}
}
frame.setVisible(true); should be last code line inside public static void main(String args[]), because you setSize to already visible JFrame (just torso contains only Toolbar with three Buttons)
every Swing code lines in public static void main(String args[]) should be wrapped into invokeLater(), more info about in Oracle tutorial Initial Thread
public class MyDrawPanel extends JPanel returns zero Dimension (0, 0) you have to override getPreferredSize for (inside) MyDrawPanel extends JPanel, use there new Dimension (300, 300) from frame.setSize(300,300); and then replace this code line (frame.setSize(300,300);) with frame.pack()
Image image = new ImageIcon("b.png").getImage();
a) don't to load any FileIO inside paintComponent, create this Object as local variable
b) 1st code line inside paintComponent should be super.paintComponent() and without reason to be public, but protected (public void paintComponent(Graphics g))
c) Dimension set in g.drawImage(image,20, 20, this); doesn't corresponding with frame.setSize(300,300);, for why reason is there empty space
d) most important (as mentioned in comments) Image image = new ImageIcon("b.png").getImage(); isn't valid Java path
try to use getClass().getResource("b.png"); instead of simply giving the file name.
Because it sometimes doesn't receive the image, so extract the path and resource.
You have to add your image (or any file) in the main project file when you work with eclipse or other frameworks
and if you decides to specialize a specific folder in the project -to hold images for example- you can write Image image = new ImageIcon("src\\b.png").getImage();//replace the src with folder name
Or add the full (absolute)path
You're declaring a JFrame called frame and correctly declaring a class that inherits from Panel that can be drawn upon. The method paintComponent(Graphics G) in MyDrawPanel.Java is called upon every time the image needs to be rewritten.
I tested out your code in my own IDE and it works for me. I think that, as others also have suggested, that your picture needs to be dragged into your Eclipse IDE. Just drag-and-drop it into your Java-project.