mixing gridlayout and borderlayout - java

I was tired but before quitting just stuck in the nearly-last 3 lines in the code snippet below to make a "refresh" button on my tictactoe panel, hoping to get away with it but expecting errors, since it mixes layout managers on a single container.
But it WORKED.
ButtonPanel.setLayout(new GridLayout(3, 3));
guiFrame.add(ButtonPanel);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
button[i][j] = addButton(ButtonPanel, i, j);
}
}
JButton refreshbutton = new JButton("Refresh");
guiFrame.add(refreshbutton, BorderLayout.SOUTH); // ... border layout worked. Hm.
refreshbutton.addActionListener(this);
guiFrame.setVisible(true); }
Should I be surprised? (Keep in mind my newbieness.)
(BOY, did I learn/stumble onto a buncha stuff in writing this silly game's program!!!--for instance, using setActionCommand to "label" each button internally [as 11,12,13,21,...33] so the ONE actionPerformed method could use getActionCommand to correctly label [with X or O] whatever button was pushed by whoever's turn it was.)

guiFrame.add(refreshbutton, BorderLayout.SOUTH); // ... border layout worked. Hm.
Just because you used BorderLayout.SOUTH does not make a panel a BorderLayout. Your code worked because the default layout manager for the content pane of a JFrame (JDialog) is a BorderLayout. So you are just taking advantage of the default layout.
since it mixes layout managers on a single container.
Yes, this is a common practice. In fact it is almost impossible to create a reasonably complex GUI if you don't use different layout managers on different panels that you add to a GUI.

Related

Is it possible to place components randomly without container in Swing window builder?

The only way, as far as I know, to put a JButton or a JLabel is via creating the GUI structure through Containers and placing those components on it.
Are there other methods to add components randomly into the frame and resize accordingly ,as can be done in Visual C# for example? What is the method to do it?
Yes.
You could use a null Layout and then place components using setBounds().
For example:
JPanel panel = new JPanel(null);
for (int i = 0; i < 4; i++) {
JButton b = new JButton("JButton-"+i);
b.setBounds(50+i*10, 50+i*10, 100, 100);
panel.add(b);
}
If you want random placing, you could random the first 2 (x,y) values.
You will need to provide on your own valid values to be placed inside the parent container.

Why does the last item added to a panel occupy the whole panel?

I'm adding a quantity of JTextField to a panel, and all of them are added but, the last one added takes the whole panel and seems all other text boxes added on the last one..... here is the code
public JPanel crearCartonFormulario() {
panel = new JPanel();
panel.setLayout(new BorderLayout());
JTextField[] textBoxes = new JTextField[25];
int cont = 0;
int posX = 10;
int posY = 0;
llenarArreglo();
while (cont <= 4) {
for (int i = 0; i <= 4; i++) {
if (cont == 2 && i == 2) {
textBoxes[i] = new JTextField("");
} else {
textBoxes[i] = new JTextField(String.valueOf(numeros[cont][i]));
}
textBoxes[i].setBounds(i + posX, 15 + posY, 40, 40);
textBoxes[i].setEditable(false);
panel.add(textBoxes[i]);
posX += 50;
}
posY += 50;
posX = 10;
cont++;
}
return panel;
}
This is returned at a panel where I keep multiple panels of this one, it works but in this one the last JTextField takes the whole panel space....
The new JFrame that contains the panels created by the method, adopt the last JTextField size and that text box doesn't take the bounds indicated by the method, but all the other text boxes still inside and correctly added.
panel.setLayout(new BorderLayout());
You are using a BorderLayout.
panel.add(textBoxes[i]);
When you use the add() method the default is to add the component to the CENTER of the BorderLayout. However, only a single component can be added to the center so the layout manager will only manage the size/location of the last component added. The rules of the BorderLayout is to make the component take up all the available space.
However, you have also used the setBounds() methods for the other text fields which is causing a problem. You should NOT attempt to use a layout manager and manage the bounds of the components yourself.
The solution is to just use a layout manager and let the layout manager do its job. Read the section from the Swing tutorial on Using Layout Managers for more information and use a more appropriate layout manager.
Update:
its a bingo table
Then maybe you shouldn't even be using JTextFields. Maybe a JTable would be a better component to use. The tutorial also has a section on How to Use Tables.
Your problem is here:
panel.setLayout(new BorderLayout());
You set the layout to BorderLayout and yet add components to the JPanel as if it were a GridLayout. Understand that when you add components to a BorderLayout-using container in a default way, the components get added in the BorderLayout.CENTER position which fills this position, covering anything added prevsiously.
Perhaps you wish to use a GridLayout instead? You will want to read the layout manager tutorial for more.
This is because you are using BorderLayout and BorderLaout Always requires a parameter like BorderLayout.CENTER, BorderLayout.WEST, BorderLayout.EAST, BorderLayout.NORTH and BorderLayout.SOUTH.
So basically BorderLayout only has 5 position where a component can go. And if you do not specify where when adding a component it defaults to BorderLayout.CENTER. And as there can only be one component at a time in the BorderLayout.CENTER position it only really adds the last one. So I'd suggest an other layout manager like GridLayout( if you want all the components to be equally sized).
I hope this helps :).
P.S. If you want me to give some explination on GridLayout just ask.

Java swing GUI creation

I'm developing a Java GUI and I need:
A label in first row(only one label).
Starting 2nd row need to add say 100 buttons which extends to multiple lines(width shouldn't go beyond the visible screen)
In a new line one more Label
From next line say 100 buttons which extends to multiple lines(width shouldn't go beyond the visible screen)...
[OPTIONAL] If the components exceeds JFrame height then need a scroll facility to the main window (only vertical)
I have a strange results with flow layout, sometimes it stick to visible width, sometimes it sets even 500 buttons in a single row.
I have tried every layout and also multipanes. Still no luck.
Please guide.. just need an idea, No need of code
Updated with code: Sorry guys, that was my first question to stackoverflow
Thanks for prompt response
Infact i tried many, here is a simple one.
setLayout(new FlowLayout());
setTitle("JAVA GUI");
setSize(500,500);
setVisible(true);
add(new JLabel("row 1"));
JPanel panel1 = new JPanel(new FlowLayout());
for(int i=0;i<200;i++){
panel1.add(new JButton("b"+i));
}
add(panel1);
Here the panel1 is appearing in a sigle row which goes beyond the visible part of the screen.
I think this can be solved by setting maximumsize to Jframe, but no idea how to set its size to FULL SCREEN.
You can try MigLayout.
http://www.miglayout.com/
Also this question is not really a question for stack overflow. A good way to ask your question would be to post your code and tell us what is wrong with it and what it is supposed to do.
While this is not the norm for 'good' stackOverflow questions, I don't have any problem with it myself. Some people cannot deal with anything except code. I would suggest that, if you're going to post code, that you take the trouble to post code that will compile, run, and demonstrate your situation. It really helps those of us out here understand what you're seeing and what you're trying to do.
You talk about "rows"; be aware that rows and columns are terms used with things like GridLayout and GridBagLayout, but I don't think they're appropriate for what you describe.
In your description, you don't say what you want scrolled. It would appear you want the entirety of the UI scrolled, I'll assume that for now.
I would try a JPanel with BoxLayout, oriented vertically, for the overall main UI. You will put some things into that:
The first JPanel.
Another JPanel, set with FlowLayout, holding the first bunch of buttons.
Another JPanel with the next JLabel
And a fourth JPanel, set with FlowLayout, holding the second bunch of buttons.
Now, I would put the top-level panel into a JScrollPane, and then put that into the CENTER section of a Frame (with its default BorderLayout), and see what happens. To tell the truth, I'm not sure, but these are the things I would start with.
I cannot tell, without running code, why you get odd behavior sometimes.
As said in a previous comment, using a ContentPane is the way to go. Here is a working example of what you want:
public class Test {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("JAVA GUI");
JPanel panel1 = new JPanel();
panel1.setLayout(new BoxLayout(panel1, BoxLayout.Y_AXIS));
int nbLines = 10;
for (int i = 0; i < nbLines; i++) {
JPanel linePanel = new JPanel(new FlowLayout());
linePanel.add(new JLabel("row " + i));
for(int j = 0; j < 50; j++) {
linePanel.add(new JButton("b" + j));
}
panel1.add(linePanel);
}
frame.setContentPane(panel1);
//frame.setSize(500, 500);
frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
frame.pack();
frame.setVisible(true);
}
}
And here is what I get:
If you want to have left-aligned buttons you can use:
JPanel linePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

Jlabel array not visible in netbeans while creating dynamically

I am not able to view the labels which are created dynamically.The code is as follows :
JLabel[] labels = new javax.swing.JLabel[cur.length];
for (int i = 0 ;i < cur.length; i++)
{
System.out.println("in");
labels[i] = new JLabel( cur[i] );
labels[i].setText(""+cur[i]);
jPanel1.add(labels[i]);
this.setVisible(true);
}
}
There can one or many of cause for your problem
1. Your JPanel may not be added to Container. Add it using getContentPane().add(jpanel1);
2. Your JLabel itself are not visible. Set their visible property to true.
3. Your JPanel is not having flowlayout but CardLayout and hence they might be visible in the back of other component. Assign the layout using jpanel1.setLayout(new FlowLayout())
4. Shift your this.setVisible(true) to outside loop.
What layout are you having for your jPanel object ? try changing its layout to say, FlowLayout. Give it layout in the beginning where you defined it and then use it in your loop.

JScrollPane always clears my Panel

Hy.. I have a JPanel, and in this contentPanel I added some other custom panels and give them locations etc. So now I added a JScrollPane to the contentPanel and always when I scroll down it clears my contentPanel, but the panels are still there but not visible...
How can I make them visible again?
That's my code to add the Panel into the contentPanel. The x,y,j are some settingsstuff for the location because I have an fixed window.
private void reloadContentPanel() {
int x = -200, y = 0, j = 1, row = 4;
EventPanel panel = null;
int i;
for(i=0; i < this.images.size();i++)
{
panel = new EventPanel(this.images.get(i).getAbsolutePath(),
this.images.get(i).getName());
panel.setLocation(x+(j*200), y);
j++;
if(i == row) {
x = -200;
y += 205;
j = 1;
row += 5;
}
this.contentPanel.add(panel);
}
this.repaint();
}
Thanks
it sounds like you are not using a LayoutManager correctly.
after creating your JFrame (i'm guessing within your constructor) add the following (for example):
this.setLayout(new FlowLayout());
this will certainly not be the best layout manager for what you are trying to do but will stop the add calls from overriding the displayed component.
you will need to read further about LayoutManagers
besides this, it's not really advisable to extend JFrame. It's better practice to treat JFrame as a member of your class just like all the other components.
I have the answer! :)
I use a GridLayout not a FlowLayout, so it's fine and it automatically refreshes the panels =)

Categories