i am creating a software for my project and here is what i have done so far..
what i am trying to do is, i have a jpane witch is created using net beans and it is inside a scrollpane(witch is also add using netbeans) and dynamically i created set of jpanes and add those jpanes in to the jpane i created using netbean.now the scrollpane doesn't work..i cant figure out the reason please help me
this is what i did
int size=(int)jSpinner1.getValue();
a=new JPanel [size];
nameoftext=new JLabel[size];
name=new JTextField[size];
but =new JButton[size];
iamge=new JLabel[size];
jPanel1.removeAll();
for(int x=0;x<size;x++)
{
a[x]=new JPanel(new FlowLayout());
jPanel1.setLayout(new BoxLayout(jPanel1,BoxLayout.PAGE_AXIS));//this is the jpanel i created using netbeans
jPanel1.add(a[x]);
a[x].setVisible(true);
}
for(int x=0;x<size;x++)
{
nameoftext[x]=new JLabel("enter name");
nameoftext[x].setText("enter name");
name[x]=new JTextField();
name[x].setName("name"+String.valueOf(x));
name[x].setColumns(20);
a[x].add(nameoftext[x]).setVisible(true);
a[x].add(name[x]).setVisible(true);
}
and there is one more thing i have to drag the border of jframe to make these components visible.. how to add them instantly to the jframe without dragging the frame
When you add (or remove) components from a visible GUI you need to revalidate() the panel to invoke the layout manager so components can be given a proper size (and location), otherwise the size is (0, 0) and there is nothing to paint.
The basic code would be:
panel.add(...);
panel.revalidate();
panel.repaint();
Related
I searched for hours for an answer,tried every method I know about and didnt find an answer.
I'm working on eclipse, my class is extending JFrame and im trying to replace two components that I added to the frame(using gridbaglayout).
When I'm removing the first one,I can't get to add the second one to where the first one was.
The components are JButton with images.
how do I get to add and remove components wherever I want? (already tried using GridBagConstraints to add it to the place I just removed a component from)
As a workaround you could add to your main panel (using GridbagLayout) inherited panels with the buttons in it. Then when you want to replace these buttons (or whatever component) you dont replace them on main panel. You replace them in the inherited panels. Since you are not giving us code, a kind of pseudocode would be like:
JButton myBtn = new JButton(); //Theinitial button
JPanel mainPanel = new JPanel(new GridBagLayout()); //main panel
JPanel inheritedPanel = new JPanel(new BorderLayout())//borderlayout to fill the entire panel.
inheritedPanel.add(myBtn,BorderLayout.CENTER);
mainPanel.add(inheritedPanel, myConstraints);
JButton replacementBtn = new JButton;
inheritedPanel.remove(myBtn);
inheritedPanel.add(replacementBtn);
inheritedPanel.repaint();
inheritedPanel.revalidate();
The components are JButton with images.
Just replace the image by using the setIcon(...) method.
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
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.
I have a simple swing application which consists of a JLabel and three buttons. The three buttons are in their own JPanel which is in a JFrame along with the JLabel. The JPanel uses flowlayout manager to arrange the buttons horizontally and the JFrame uses the BorderLayout manager to arrange the JLabel and JPanel vertically.
My problem is when I launch the application, during the course of use the text on one of the buttons changes which increases its width. However, the window doesn't resize to accomdate this and one of the buttons disappears. I thought about calling pack() again, but the JFrame is a local variable in my constructor, also, I shouldn't have to tell my program to resize, right? I haven't been able to find anything on google or here to help me but there must be a simple solution, what am I missing? Code is below.
playButton = new JButton("Play");
pauseButton = new JButton("Pause");
stopButton = new JButton("Stop");
curTrackLabel = new JLabel("No Track Selected");
JFrame myFrame = new JFrame("MediaPlayer");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setTitle("MediaPlayer");
myFrame.setLocation(400,300);
JPanel topPanel = new JPanel();
topPanel.setLayout(new BorderLayout());
myFrame.add(topPanel);
JPanel buttonPanel = new JPanel(new FlowLayout());
buttonPanel.add(playButton);
buttonPanel.add(pauseButton);
buttonPanel.add(stopButton);
topPanel.add(buttonPanel, BorderLayout.CENTER);
topPanel.add(curTrackLabel, BorderLayout.NORTH);
playButton.addActionListener(new playButtonHandler());
pauseButton.addActionListener(new pauseButtonHandler());
stopButton.addActionListener(new stopButtonHandler());
myFrame.pack();
myFrame.setVisible(true);
Maybe try
((JFrame)myButton.getTopLevelAncestor()).pack();
Where myButton is the button whose text is modified during execution.
As with learning any GUI software, experimentation is best. Try messing with BorderLayouts with nested JPanels.
Ultimately, you use JPanel with a BorderLayout (Flow Layout is OK but really when resizing the window, it epically fails). See http://download.oracle.com/javase/tutorial/uiswing/layout/border.html to learn more about BorderLayouts.
Now for your layout scheme it should be something along the lines of:
Top Level Container: JFrame
JFrame contains a JPanel (Call this
JPanel 1) with a BorderLayout.
The three buttons should be in a
SEPARATE jPanel (JPanel 2). JPanel
1 should add the three buttons as
BorderLayout.CENTER. In this way,
the window will resize if the button
changes its width and/or hright.
The JLabel should be added as
BorderLayout.LINE_START.
The tutorial at: http://download.oracle.com/javase/tutorial/uiswing/layout/border.html should help you with this. But in general, use the following:
Use JPanel and nest JPanels as necessary
BorderLayout.CENTER will accomodate size changes---this is the key! (Experiment with this)
JFrame should only be used as a top level container (for more complex GUIs, this is true).
If you require more flexibility, check out JGoodies: http://www.jgoodies.com/ . This is more along the lines of creating forms.
I'm building a little app using Java and Swing in NetBeans. Using NetBeans design window, I created a JFrame with a JPanel inside.
Now I want to dynamically add some jTextFields to the JPanel.
I wrote something like that:
Vector textFieldsVector = new Vector();
JTextField tf;
int i = 0;
while (i < 3) {
tf = new JTextField();
textFieldVector.add(tf);
myPanel.add(tf); //myPanel is the JPanel where I want to put the JTextFields
i++;
}
myPanel.validate();
myPanel.repaint();
But nothing happens: when I run the app, the JFrame shows with the JPanel inside, but the JTextFields don't.
I'm a total newbie in writing graphical Java apps, so I'm surely missing something very simple, but I can't see what.
In the Netbeans GUI, set the layout manager to something like GridLayout or FlowLayout (just for testing). You can do this by going to the GUI editor, clicking on your panel, and then right-clicking and selecting a layout.
Once you've changed to a different layout, go to the properties and alter the layout properties. For the GridLayout, you want to make sure you have 3 grid cells.
Instead of myPanel.validate(), try myPanel.revalidate().
The more canonical way to do this is to create a custom JPanel (without using the GUI editor) that sets its own layout manager, populates itself with components, etc. Then, in the Netbeans GUI editor, drag-and-drop that custom JPanel into the gui editor. Matisse is certainly capable of handling the runtime-modification of Swing components, but that's not the normal way to use it.
It's been a while since I've done some Swing but I think you'll need to recall pack() to tell the frame to relayout its components
EDIT: Yep, I knew it had been too long since I did Swing. I've knocked up the following code which works as expected though and adds the textfields...
JFrame frame = new JFrame("My Frame");
frame.setSize(640, 480);
JPanel panel = new JPanel();
panel.add(new JLabel("Hello"));
frame.add(panel);
frame.setLayout(new GridLayout());
frame.pack();
frame.setVisible(true);
Vector textFieldVector = new Vector();
JTextField tf;
int i = 0;
while (i < 3) {
tf = new JTextField();
textFieldVector.add(tf);
panel.add(tf); //myPanel is the JPanel where I want to put the JTextFields
i++;
}
panel.validate();
panel.repaint();
Your while loop is wrong. i never gets incremented so your window creation is in an endless loop and your CPU consumption should be at 100% until you abort the program. Also, the GUI should be completely non-responsive when you run your program.
The usual way to use GroupLayout is to add a component to a Group. GroupLayout keeps a reference to the Container it is responsible for (which makes sense). You shouldn't be adding the component to the panel without constraints.
Don't use GroupLayout with new (dynamically added) component. It won't show up.
Just use the .setVisible() method of JTextField:
JTextField tf = new JTextField() ;
tf.setVisible(true) ;
panel.add(tf) ;