I am having some issues regarding jframe and jlabel? - java

I am making simple login screen. I added two JLabel's in JFrame in my program and it's running successfully but the problem is that when I run the program I got blank screen and empty jframe, however I have added two jlabel's in that frame but it's not showing me any thing and then if I minimize the window and after some time if I open that window again then I can see those components.
Here is my code:
package javaapplication41;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.*;
public class JavaApplication41 {
JavaApplication41()
{
JFrame cpec=new JFrame();
cpec.setBounds(300,200,600,350);
cpec.setUndecorated(false);
cpec.setVisible(true);
cpec.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel l = new JLabel(new ImageIcon("C:\\Users\\MUHAMMAD SHAHAB\\Documents\\NetBeansProjects\\Real Estate\\src\\real\\estate\\file (2).jpg"));
l.setBounds(100,100,200,125);
//l.setLayout(null);
cpec.add(l);
JLabel kiq=new JLabel(new ImageIcon("C:\\Users\\MUHAMMAD SHAHAB\\Documents\\NetBeansProjects\\Real Estate\\src\\real\\estate\\bla.jpg"));
kiq.setBounds(100,100,100,100);
//kiq.setLayout(null);
l.add(kiq);
}
public static void main(String[] args) {
JavaApplication41 ne=new JavaApplication41();
}
}
I am getting this output when I run program:
and when I minimize this window and again open this, then I am getting the desired output here it is:
what am I doing wrong?

You have to put cpec.setVisible(true); after adding all the items in your jframe.I hope this will surely solve your problem

You have set the visibility of JFrame at a very early stage. At that time the JLabel was not added. When you minimized and resized your frame, it got rendered again resulting in showing your added components.
Remember to add components before setting the Frame's visibility( set visibility at last).
Also I would suggest you to use GUI threads when working on swing components. Refer to swing utilities here : https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
Lastly set the layout of JFrame to null as you are trying to add labels to specific coordinates with setBounds() method.

Default layout of jframe is BorderLayout, so if you want you can change layout by reference of java.awt.Container abstract class.
It is initialized by getContentPane() of javax.swing.JFrame class.
The components are added only through reference of java.awt.Container class.
java.awt.Container c=cpec.getContentPane();
c.setLayout(new FlowLayout(FlowLayout.LEFT));
c.add(l); //label will get added to JFrame instance that is referenced
//then define size and at last define visibility
cpec.setSize(500, 500);
cpec.setVisible(true);

Set the Layout manager of the container as null. By default it uses BorderLayout as its Layout manager. You just have to call the getContentPane() method using the reference of the JFrame, which returns a container reference. Example:
Container c = frame.getContentPane();
c.setLayout(null);
For more information you can go through my Website.

Related

Swing - Get to the next "page" when pressing a button [duplicate]

To put it simple, there's a simple java swing app that consists of JFrame with some components in it. One of the components is a JPanel that is meant to be replaced by another JPanel on user action.
So, what's the correct way of doing such a thing? I've tried
panel = new CustomJPanelWithComponentsOnIt();
parentFrameJPanelBelongsTo.pack();
but this won't work. What would you suggest?
Your use case, seems perfect for CardLayout.
In card layout you can add multiple panels in the same place, but then show or hide, one panel at a time.
1) Setting the first Panel:
JFrame frame=new JFrame();
frame.getContentPane().add(new JPanel());
2)Replacing the panel:
frame.getContentPane().removeAll();
frame.getContentPane().add(new JPanel());
Also notice that you must do this in the Event's Thread, to ensure this use the SwingUtilities.invokeLater or the SwingWorker
frame.setContentPane(newContents());
frame.revalidate(); // frame.pack() if you want to resize.
Remember, Java use 'copy reference by value' argument passing. So changing a variable wont change copies of the reference passed to other methods.
Also note JFrame is very confusing in the name of usability. Adding a component or setting a layout (usually) performs the operation on the content pane. Oddly enough, getting the layout really does give you the frame's layout manager.
Hope this piece of code give you an idea of changing jPanels inside a JFrame.
public class PanelTest extends JFrame {
Container contentPane;
public PanelTest() {
super("Changing JPanel inside a JFrame");
contentPane=getContentPane();
}
public void createChangePanel() {
contentPane.removeAll();
JPanel newPanel=new JPanel();
contentPane.add(newPanel);
System.out.println("new panel created");//for debugging purposes
validate();
setVisible(true);
}
}
On the user action:
// you have to do something along the lines of
myJFrame.getContentPane().removeAll()
myJFrame.getContentPane().invalidate()
myJFrame.getContentPane().add(newContentPanel)
myJFrame.getContentPane().revalidate()
Then you can resize your wndow as needed.
Game game = new Game();
getContentPane().removeAll();
setContentPane(game);
getContentPane().revalidate(); //IMPORTANT
getContentPane().repaint(); //IMPORTANT
It all depends on how its going to be used. If you will want to switch back and forth between these two panels then use a CardLayout. If you are only switching from the first to the second once and (and not going back) then I would use telcontars suggestion and just replace it. Though if the JPanel isn't the only thing in your frame I would use
remove(java.awt.Component) instead of removeAll.
If you are somewhere in between these two cases its basically a time-space tradeoff. The CardLayout will save you time but take up more memory by having to keep this whole other panel in memory at all times. But if you just replace the panel when needed and construct it on demand, you don't have to keep that meory around but it takes more time to switch.
Also you can try a JTabbedPane to use tabs instead (its even easier than CardLayout because it handles the showing/hiding automitically)
The other individuals answered the question. I want to suggest you use a JTabbedPane instead of replacing content. As a general rule, it is bad to have visual elements of your application disappear or be replaced by other content. Certainly there are exceptions to every rule, and only you and your user community can decide the best approach.
Problem: My component does not appear after I have added it to the container.
You need to invoke revalidate and repaint after adding a component before it will show up in your container.
Source: http://docs.oracle.com/javase/tutorial/uiswing/layout/problems.html
I was having exactly the same problem!! Increadible!! The solution I found was:
Adding all the components (JPanels) to the container;
Using the setVisible(false) method to all of them;
On user action, setting setVisible(true) to the panel I wanted to
show.
// Hiding all components (JPanels) added to a container (ex: another JPanel)
for (Component component : this.container.getComponents()) {
component.setVisible(false);
}
// Showing only the selected JPanel, the one user wants to see
panel.setVisible(true);
No revalidate(), no validate(), no CardLayout needed.
The layout.replace() answer only exists/works on the GroupLayout Manager.
Other LayoutManagers (CardLayout, BoxLayout etc) do NOT support this feature, but require you to first RemoveLayoutComponent( and then AddLayoutComponent( back again. :-) [Just setting the record straight]
I suggest you to add both panel at frame creation, then change the visible panel by calling setVisible(true/false) on both.
When calling setVisible, the parent will be notified and asked to repaint itself.
class Frame1 extends javax.swing.JFrame {
remove(previouspanel); //or getContentPane().removeAll();
add(newpanel); //or setContentPane(newpanel);
invalidate(); validate(); // or ((JComponent) getContentPane()).revalidate();
repaint(); //DO NOT FORGET REPAINT
}
Sometimes you can do the work without using the revalidation and sometimes without using the repaint.My advise use both.
Just call the method pack() after setting the ContentPane, (java 1.7, maybe older) like this:
JFrame frame = new JFrame();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
....
frame.setContentPane(panel1);
frame.pack();
...
frame.setContentPane(panel2);
frame.pack();
...

I can't to get Label and Buttons components in created window

I tryed to learn about GUI and tryed to create the window with two buttons and jne Label on the screen. But I don't understand why I can't see these elements simultaneously. When I comment out lines for buttons I can see the Label element.
Here is my code:
import java.awt.*;
import javax.swing.*;
public class MyWin {
public static void main(String[] args) {
JFrame w = new JFrame("My Window");
w.setSize(1000,800);
w.setVisible(true);
JButton b = new JButton("My button");
b.setVisible(true);
b.setSize(150, 100);
b.setLocation(500, 20);
JButton b2 = new JButton("Second button");
b2.setVisible(true);
b2.setSize(150,100);
b2.setLocation(500, 600);
JLabel l = new JLabel("My label");
l.setVisible(true);
w.getContentPane().add(b);
w.getContentPane().add(b2);
w.getContentPane().add(l);
}
}
The default layout for the JFrame is BorderLayout and when you add your JLabel through single parameter add method you add it with a BorderLayour.CENTER constraint as a default, this causes to fill all the available space. So you might want to use layout manager suitable for your needs, then the components won't overlay themselves.
Visual Guide to Layour Managers
First of all, JFrame uses BorderLayout as a default layout and just adding the components (w.getContentPane().add(b)) sets them in BorderLayout.CENTER; where they occupy the whole JFrame to fill the empty space. Thus, is recommended to add components in a JPanel. So, you should create first a JPanel, add the components to the JPanel and finally add it to the JFrame.
The setSize(...); statement is not applied due to the default layout (FlowLayout) in JPanels and also is discouraged. (Because it won't work properly in different computers with different screen resolutions)
If you want to change the size of the components you should change the default layout and use instead a customLayout, borderLayout, gridLayout...
If you want to understand deeply how layouts work and all the available layouts in Java check this

displaying labels and textfields in java swings

I can't understand why in the following code only the button is being displayed , and why aren't label and textfield displayed.
import javax.swing.*;
import java.awt.*;
class Invent extends JFrame
{
public Invent(){
JFrame c=new JFrame("trying");
JLabel label1;
JTextField txtfld1;
JButton buttoncomp;
label1=new JLabel("Enter the path");
txtfld1=new JTextField();
buttoncomp=new JButton("Update");
c.add(label1);
c.add(txtfld1);
c.add(buttoncomp);
c. pack();
c.setVisible(true);
}
public static void main(String[] args)
{
new Invent();
}
}
Kindly help ...
The default layout of a JFrame's content pane is BorderLayout. You're adding all of your components to the BorderLayout.CENTER location (by calling the single-argument add() function), which means that only the last component is added.
Either use a different layout manager, or add the components to different locations in the BorderLayout.
More info about BorderLayout can be found here.
Btw, your title has nothing to do with your actual question: the difference between a JFrame and a content pane is that a JFrame contains a content pane. The JFrame class passes calls like setLayout() and add() to its content pane.
It works incorrect(for you but java does what you say :) )
cause you add (these)three components to JFrame in row(the next remove the last)
you must work as follows:
label1.add(txtfld1);
label1.add(buttoncomp);
c.add(label1);
c.pack();
c.setVisible(true);
And something other...
You had made a new JFrame you dont need to extend it(in you class).
It's not good to add label(without panel) in HeavyWeight Component like JFrame you may have problems with Listeners(mouse,action,whatever...)
Let me know if that works for you...

How can I get the size of the inner part of a frame?

How can I get the size of the inner part of a frame? I mean the part that components can be added on.
When I'm using .NET languages like VB and C#, I do some trick. I add a panel or something alike to my form and make it fill the form (using dock property in Windows Forms), and then use its size.
I have tried hard to do this in Java, but no success. I tried to add a JPanel to CENTER of my JFrame using a BorderLayout, but although the panel fills the frame, all the size-relative functions of the JPanel return 0.
Try using getContentPane and getWidth/getHeight:
getContentPane().getWidth()
getContentPane().getHeight()
Tested with a simple 1440x900 frame and I get 1424x862
You are probably calling size related functions when the frame is not yet visible.
You can use:
getContentPane().getSize();
after invoking frame's setVisible(true) method. Getting the size of the panel added to the center of the frame, as you did before, will also work, after setting the frame to be visible.
Your way seems to work. But:
You don't need to manually add a JPanel. getContentPane() is suitable.
If you want to get its size. You need to
Makes this JFrame displayable by connecting it to a native screen resource.
Revalidates the JFrame.
setVisible(true) do these for you. But if you do not want to make the JFrame visible, you can use addNotify and revalidate.
Example:
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame();
Container c = f.getContentPane();
f.setSize(800, 600);
System.out.println(c.getSize()); // width=0,height=0
f.addNotify();
f.revalidate();
System.out.println(c.getSize()); // width=784,height=562
f.setVisible(true);
System.out.println(c.getSize()); // width=784,height=562
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
}

only JLabel not showing up

I am writting a simple application which has a button that opens a new window then display a simple GUI/Text to acccept inputs from a user. but for some reason, I can get JLabel to be displayed on the new window. The application has following structure:
+mainFrame - JFrame
+newFrame - JFrame
-+newPanel - JPanel
----title - JLabel
----submitButton -JButton
...
Buttons and textfields all display fine, but Jlabels won't show up at all. I have tried using different layouts and all but I still can't get it shown. JLabels inside mainFrame tree, works fine.. so it seems like the problem is due to newFrame declaration or something, but then button should not be displayed either. Well, I am kindda lost and can someone suggest me what I should check?
Thanks : )
Make sure you do frame.pack() before you make it visible.
It can also help to set borders on different components (in different colours) for debugging just to see which components are/aren't turning out with size 0, in order to narrow down your problem. Logging, or breakpointing the component's setSize method, can help too.
Apart from that, maybe post some sample code? At the moment, you're question is fairly vague to answer.
Firstly, do you know about JDialog, and JOptionPane - these classes are often a better way of showing another popup window. It is quite rare to use 2 JFrames, (though sometimes a sensible thing to do).
Secondly have you done pack() and setVisible(true)?
The code below works fine for me. Either this breaks for you and it is something about your Java implementation, or you must be doing something different, in which case can you tell us what it is:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class JLabelShower {
public static void main(String [] args) {
JFrame mainFrame = new JFrame("main frame");
JButton popup = new JButton("start new frame");
mainFrame.getContentPane().add(popup);
mainFrame.pack();
mainFrame.setVisible(true);
popup.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFrame newFrame = new JFrame("new frame");
JPanel newPanel = new JPanel();
JLabel title = new JLabel("title");
newPanel.add(title);
newFrame.setContentPane(newPanel);
newFrame.pack();
newFrame.setVisible(true);
}
});
}
}
In case you are using the JLabel as a placeholder, i.e. initialize it with an empty string and set the text later:
Since the JLabel's size gets calculated when the panel gets layed out (i.e. early on) and is based on the contained text, you'll probably end up with a label thinking it has a preferred size of (0, 0).
In this case you should tell the label what size it should ask for by calling setPreferredSize with an appropriate value.
And another cause might be the layoutmanager you are using in the surrounding panel. Maybe you are adding the label and the button in the same place, e.g. BorderLayout.CENTER. That would explain why only one of the two gets displayed.
Set the opacity of the JLabel object to true using title.setOpaque(true) . It will paint every pixel within bound of the JLabel object. This solved my problem of same type.

Categories

Resources