Why can't I position the JButton using setLocation in this code? - java

I am very new and still have a lot to learn. Thank you so much for anyone who takes the time to help me with this. I have tried a variety of different methods to position my button at specific coordinates with the frame, but for some reason, none of the usual statements that work for placing JButtons is working. Any suggestions?
Here is my current working code
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class GUI extends JFrame
{
JButton b1; // Declares Swing button variable and gives identifier (b1)
JButton b2; // Declares Swing label variable and gives identifier (l1)
public GUI()
{
setTitle("Virus Explortation");
setSize(400,400);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
setLayout(new BorderLayout());
setContentPane(new JLabel(new ImageIcon("C:\\Pictures\\matrix.gif")));
setLayout(new FlowLayout());
b1=new JButton("I am a button");
add(b1);
b2=new JButton("I am also a button");
add(b2);
setSize(399,399);
setSize(400,400);
}
public static void main(String args[])
{
new GUI();
}
}

Why can't I position the JButton using setLocation in this code?
It is because all the containers in Java swing has a default layout. You are adding the button directly into the JFrame where I see you using a BorderLayout for the frame. (BorderLayout is also the default layout for JFrame).
When a layout is used, the layout manager will decide on the position (and sometimes the dimension) for your added components. Which means your attempt of manually setting the position may become futile.
If you want to set the components' position to exactly where you want, you will have to set the layout of the container (such as JFrame or JPanel) to null:
JPanel pnlMain = new JPanel();
pnlMain.setLayout(null);
After you set it to null, you will have to set the location for every components you add to the container. If not, it won't show up. You may use the setBounds method to set the size and location:
JButton btn = new JButton();
btn.setBounds(x, y, width, height);
However, setting layout to null is not recommended for many reasons. One of the most prominent reason being that you loses control and predictability on how your UI will present on different Systems and different usage by the users.
It is also advisable not to extends from JFrame but rather extends from a container like JPanel. Then add the container to the frame. It is quite rare that you need to make a customized JFrame.

Related

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...

Java - placing items in JPanel like in JFrame

I try to do simple game, made of few 'screens' (menu, options, etc), which could work by displaying and hiding several JPanels. When I add some stuff on each panel and run the program, the only thing that appears is empty JFrame. I've made id looking like this:
public class Frame extends JFrame{
JPanel panel1 = new JPanel();
JFrame frame = new JFrame("halo");
JButton button = new Button();
int WIDTH=600,HEIGHT=600;
public Frame(){
frame.add(game);
frame.setSize(WIDTH, HEIGHT);
frame.setVisible(true);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel1);
panel1.setBounds(0,0,WIDTH,HEIGHT)
panel1.add(button);
button.setBounds(10,10,30,30);
}}
Everything essential is imported and declared, it's just 'simpled' version. What's wrong with it?
A few things:
Using the classname Frame may conflict with java.awt.Frame.
You have to set the frame visible by calling frame.setVisible(true); Before that, call frame.pack();
You are subclassing JFrame, but also declaring and preparing a different JFrame. Eliminate one of them.
Add the components to the content pane of the JFrame: frame.getContentPane().add(subcomponent);
Setting a layout manager and packing after adding elements should fix the issue. Also it's unclear why you're referring to frame when you're constructing this. Try this version:
public class Frame extends JFrame{
JPanel panel1 = new JPanel();
JButton button = new Button();
int WIDTH=600,HEIGHT=600;
public Frame(){
setTitle("Halo");
setLayout(new BorderLayout());
add(panel1, BorderLayout.CENTER);
panel1.setBounds(0,0,WIDTH,HEIGHT);
panel1.setLayout(new BorderLayout());
panel1.add(button, BorderLayout.SOUTH);
button.setBounds(10,10,30,30);
pack();
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
JFrame uses a BorderLayout by default, this means that only one component can occupy each of the five available positions that BorderLayout managers.
By default, if you don't specify where you want the component to be, it will be added to the CENTRE position
You should break your UI down into logical units and use JPanels to manage them
You can use a combination of panels and layouts to generate complex UIs
You should also consider using a CardLayout to allow you to switch between base views
You should also call setVisible on the JFrame last, after you've established the basic UI, otherwise you'll need to call revalidate and and repaint to update the UI
You should avoid using setBounds/setSize/setLocation on components and rely on the use of layout managers, as they are designed to manage the differences in rendering pipelines that occurs across multiple different operating systems and hardware platforms

basic questions in swing components in Java?

my question is could be very basic in terms of understanding this simple code. I wrote this code myself grabbing bits of code from here and there to understand. I would like to actually follow this code line by line as to what each line means?
I have added my understanding as comments above the line of code, it could be wrong or some of them marked as **** means I just dont know what it means. If you could help me out here, it will be great.
Thanks
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.text.ParseException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class TestingSwingComponents {
public TestingSwingComponents() {
//Create a frame which is the window that pops up
JFrame myframe = new JFrame();
//*****
myframe.getContentPane().setLayout(new BorderLayout());
//set the frame size to be 600 X 600 size
myframe.setSize(600, 600);
// create Pane1
JPanel myPanel = new JPanel();
//set the Layout component of Panel, as how you would like it to be
//here it is 2 rows and 15 columns
myPanel.setLayout(new GridLayout(2, 15));
//create a button with text in it
JButton letterButton = new JButton("click Me");
//add the created button component to the panel
myPanel.add(letterButton);
//******
myframe.getContentPane().add(myPanel, BorderLayout.SOUTH);
// create another panel
JPanel panelFormat = new JPanel();
//create a textfield
JTextField txtfield = new JTextField();
//create a label for the textfield
JLabel label = new JLabel("Guesss");
//set the layout type for this panel
panelFormat.setLayout(new BorderLayout());
//add label to panel
panelFormat.add(label);
//add textfield to panel
panelFormat.add(txtfield);
//I dont know the difference between the below two
//BorderLayout.CENTER still does not center the panel in the frame, I dont know why
myframe.getContentPane().add(panelFormat, BorderLayout.CENTER);
myframe.add(panelFormat);
// default settings
myframe.setTitle("Get buttons");
myframe.setVisible(true);
myframe.setLocationRelativeTo(null);
myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) throws ParseException {
new TestingSwingComponents();
}
}
myframe.getContentPane().setLayout(new BorderLayout());
To answer this, you need to understand the structure of a Swing window. A JFrame (in fact any Swing window) is made up a series of components which generate the view of the window.
(Picture from How to use Root Panes)
A JRootPane makes up the base of view, on-top of which is a JLayeredPane and what is know as the "glass pane". The JLayeredPane is responsible for managing the JMenuBar and the "content pane".
The content pane is where you components reside on the window.
So, what this line is saying is, "get the frame's content pane and set it's layout to use a BorderLayout"
The layouts API is an entire question on it's own and it would be use to you to have a read through Laying out components within a container for a more indeepth description, but basically, layout managers remove the need for you to care (a greate deal) about differences in rendering techniques employeed by different systems...
//******
myframe.getContentPane().add(myPanel, BorderLayout.SOUTH);
This comes back to the layout manager. Because you can have any number of layout managers, Swing allows you to pass a "constraint" to the layout manager when you add the component, giving the layout manager some idea of how you might like this component to be added.
If you take a closer look at BorderLayout you will see that it has five positions in which components can be added.
The line is basically saying, "please add myPanel to the SOUTH position within the frame/content pane"
Update from comments
If you have a look at this snippet...
panelFormat.setLayout(new BorderLayout());
//add label to panel
panelFormat.add(label);
//add textfield to panel
panelFormat.add(txtfield);
It sets the layout manager for panelFormat to BorderLayout. BorderLayout can only have a single component in any of it's five available positions. When you use add(Component) without passing it a layout constraint, BorderLayout use CENTER as the default position, this means you are trying to add two components to the CENTER position, this is not possible, so BorderLayout simply uses the last component that was added.
why not borderlayout fix the size of textfield instead of stretching
it all window
Because this is how BorderLayout works and no, GridLayout would probably do something simular.
You could try FlowLayout or GridBagLayout
Updated from comments
You seriously need to take the time to read through the linked (and other suggested) tutorials...but basically, you can use a GridBagLayout just like any other layout, you create an instance of it and apply it to the container...
// create another panel
JPanel panelFormat = new JPanel();
//create a textfield
JTextField txtfield = new JTextField(10);
//create a label for the textfield
JLabel label = new JLabel("Guesss");
//set the layout type for this panel
panelFormat.setLayout(new GridBagLayout());
//add label to panel
panelFormat.add(label);
//add textfield to panel
panelFormat.add(txtfield);
//I dont know the difference between the below two
//BorderLayout.CENTER still does not center the panel in the frame, I dont know why
myframe.getContentPane().add(panelFormat, BorderLayout.CENTER);
myframe.add(panelFormat);
A Swing top-level container, including a JFrame, JDialog is composed of several components all held together including a JRootPane which holds all together, a JLayeredPane, and a contentPane the latter of which holds most of the GUI excepting the top window bar. You can read more about the details in this tutorial here: Top Level Containers:
So when you add a component to a JFrame in a default way, you're actually adding it to its contentPane. In other words, this:
myJFrame.add(myComponent);
is functionally the same as this:
myJFrame.getContentPane().add(myComponent);
For learning Swing, I used this great tutorial which goes over everything you have, and explains it pretty clearly in depth.
The tutorial also goes over the elements that you are having trouble understanding.
Here is said tutorial.

Java - How can I edit the size and position of a button using Swing?

I have the following code but I'd like to structure several buttons of certain sizes. I'm just wondering how to do this as I've Googled it and found several different methods but none seem to work. Any advice?
import javax.swing.*;
public class GUI {
public static void main(String[] args) {
JFrame window = new JFrame();
window.setSize(500, 500);
window.setTitle("My Application");
JButton button = new JButton("click me");
window.add(button);
window.setVisible(true);
}
}
It looks like you are taking your first steps into swing. The questions that you are asking belong to an area of gui design called layout. Exactly how you set the position of your button depends hea ily on the layout. I would suggest that you find a swing tutorial and run through it. I started with the Java Swing Trail: http://download.oracle.com/javase/tutorial/uiswing
In the Java api documents look for BorderLayout and GridLayout. They are the easiest to start with.
From your question I think you are trying to make the button fit the size of the window. In which case you would use window.add(button, BorderLayout.CENTER);
If you are trying to have multiple buttons you need to use a layout. A tutorial for making GUIs in swing using layouts can be found here.
In general you can use setLocation and setSize methods. However, it is best if you use a layout manager. Check Using Layout Managers tutorial. In your case by default BorderLayout is used. If you want an absolute layout you can set it:
window.setLayout(null);
Then you must specify the size and position of every component within that container.
EDIT:
Please note that using absolute layout can be complex and usually can be avoided. See A Visual Guide to Layout Managers for some ideas.
You really can change the size of your JButton in number of different ways, but it is not a good practice at all to do that in swing, and explicitly give size values to different components. You must better start learning about Layout Managers. And it will be much wiser, if you will also learn about Concurrency in Swing.
The default Layout for the JFrame is BorderLayout, as the default for JPanel is FlowLayout.
But as for your question, the simplest way I can think of is as follows :
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
public class GUI {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
/*
* THe default Layout for the JFrame is the BorderLayout.
* Since you said you have some buttons, so I am giving
* you some idea how various buttons can be added to the
* JFrame, with different values.
*/
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLocationRelativeTo(null);
window.setTitle("My Application");
JButton button1 = new JButton("Button1");
window.add(button1, BorderLayout.PAGE_START);
JButton button2 = new JButton("Button2");
window.add(button2, BorderLayout.WEST);
JButton button3 = new JButton("Button3");
window.add(button3, BorderLayout.CENTER);
JButton button4 = new JButton("Button4");
window.add(button4, BorderLayout.EAST);
JButton button5 = new JButton("Button5");
window.add(button5, BorderLayout.PAGE_END);
window.pack();
window.setVisible(true);
}
});
}
}
Hope this might help you in some way.
Regards
A JButton extends an AbstractButton which in turn extends a JComponent, so, as is the case of inheritance, you can use all the methods provided by JComponent.
Related methods you should consider are:
setMaximumSize(Dimension maximumSize) Sets the maximum size of this component to a constant value.
setMinimumSize(Dimension minimumSize) Sets the minimum size of this component to a constant value.
Moreover, JComponent extends Component which provides, and you can use,
setSize(Dimension d) Resizes this component so that it has width d.width and height d.height.
setSize(int width, int height) Resizes this component so that it has width width and height height.
see the inheritance below:
java.awt.Component
java.awt.Container
javax.swing.JComponent
javax.swing.AbstractButton
javax.swing.JButton

Categories

Resources