GridBagLayout is not working when I add it to the JFrame - java

I'm having some issues with my GridBagLayout. I have created a JPanel (in this case it's called mainPanel), whose layout has been set to GridBagLayout. I have specified the constraints for each JButton, and added the constraints to each button. Now, when I run my code, the buttons are always next to each other, irrespective of the gridx/gridy value that I indicate in the constraints. Furthermore, the buttons are always at the center of the JFrame, when I would like one button to appear at the top right, top left, and south.
import javax.swing.*;
import java.awt.*;
public class test {
public static void main (String[] args) {
myJFrame test = new myJFrame();
}
}
class myJFrame extends JFrame {
public myJFrame () {
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPanel myPanel = new mainPanel();
add(myPanel);
setVisible(true);
}
}
class mainPanel extends JPanel {
public mainPanel(){
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.NORTHWEST;
c.gridx = 1000;
c.gridy= 1;
add(new JButton("1"),c);
c.anchor = GridBagConstraints.NORTHEAST;
c.gridx = 100;
c.gridy= 1;
add(new JButton("2"),c);
c.anchor = GridBagConstraints.SOUTH;
c.gridx = 200;
c.gridy= 1;
add(new JButton("3"),c);
}
}
This is what i get when i run the code

Now, when I run my code, the buttons are always next to each other, irrespective of the gridx/gridy value that I indicate in the constraints.
Correct, you can't just specify random cells. A component must be located in each cell.
Furthermore, the buttons are always at the center of the JFrame,
Yes, this is the default behaviour if you don't specify a weightx/weighty constraint.
Read the section from the Swing tutorial on How to Use GridBagLayout for more information on constraints and working examples.
Why are you picking random x locations like 100, 200, 1000? Maybe a horizontal BoxLayout would be a better layout manager. You can add the components and then add space between them:
panel.add( button1 );
panel.add( Box.createHorizonalStrut(100);
panel.add( button2 );
panel.add( Box.createHorizonalStrut(200);
Or maybe use a FlowLayout and specify the "gap" between each component.

Related

JButton in GridBagLayout in a JPanel

I am learning swing from past week, I have some issue with GridBagConstraints to put one button in top left corner but all other buttons in default in GridBagConstraints ?
I am using code that like not original but states the problem
import java.awt.*;
import javax.swing.*;
#SuppressWarnings("serial")
class MyPanel extends JPanel
{
JButton menu = new JButton("Menu"), button = new JButton("Puzzle");
GridBagConstraints gbc1 = new GridBagConstraints(), gbc2 = new GridBagConstraints();
private void setup()
{
gbc1.anchor = GridBagConstraints.FIRST_LINE_START;
gbc2.anchor = GridBagConstraints.CENTER;
gbc2.weightx = 1.0;
gbc2.weighty = 1.0;
}
public MyPanel()
{
this.setLayout(new GridBagLayout());
this.setup();
this.button.setPreferredSize(new Dimension(250, 140));
this.add(menu, gbc1);
this.add(button, gbc2);
}
}
#SuppressWarnings("serial")
public class Test extends JFrame
{
public Test()
{
this.setTitle("Test");
this.setContentPane(new MyPanel());
this.setResizable(false);
this.setSize(800, 600);
this.setVisible(true);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(() -> new Test());
}
}
output
I want menu is top corner.
I read from here but i did not understand this Could you please explain GridBagConstraints for how to do that.
I Hope that problem is clear to understand, if not please let me know in comments.
EDIT:
#camickr suggestion works but a little problem, the Puzzle Button is not in extract center.
Thanks.
By default the GridBagLayout will display all the components centered horizontally and vertically, unless one of the components has a weightx/weighty value not equal to 0. Then that component will fill the extra space in the frame.
So if you want one component at the "top/left" and one in the "center", you need to:
use the "anchor" constraint. It will be different for both components.
the component in the center will need to use the "weightx/weighty" constraints.
However, an easer solution might be to use a combination of panels with different layout managers.
For example:
JPanel menuPanel = new JPanel( new FlowLayout(FlowLayout.LEFT) );
menuPanel.add(menuButton);
JPanel centerPanel = new JPanel( new GridBagLayout() );
centerPanel.add(puzzle, new GridBagConstraints());
frame.add(menuPanel, BorderLayout.PAGE_START);
frame.add(centerPanel, BorderLayout.CENTER);
So now the "top" of the frame will contain a panel with components displayed from the left and the "center" of the frame will contain your puzzle centered in the remaining space of the frame.
Edit:
I solved it but put gridx and gridy to 0 in center component, but i did not completely understand the setttings
Well I mentioned that you would need to use the gridx/gridy constraints. You should always use those constraints as it is very obvious what grid you want to add the component to. The examples from the tutorial always specify those values.
Using gridx/gridy both equal to 0, does not really make sense. The effect is that you have two components trying to share the same grid.
Remove the setResizable(false) statement and shrink the size of the frame to see how the button repositions itself.
It is not normal that two components share the same grid. Normally you would have the menu on the first row and the button on the second row. This will center the button horizontally in the frame and vertically in the space below the menu.
What you are doi

gridheight doesn't affect my buttons

I am new in java applications and I am trying to create a window with 3 buttons in a row at the bottom of the window with extended size. However gridheight doesn't have any affect on my buttons. gridwidth works fine.
Can you give me a feedback on what I am doing wrong? I guess I haven't understand something correctly.
Bellow is my code and the output window.
Thanx in advance!
private JButton button1;
private JButton button2;
private JButton button3;
public SessionTasksPage()
{
JPanel p1=new JPanel(new GridBagLayout());
JPanel p2=new JPanel();
button1 = new JButton("b1");
button2 = new JButton("b2");
button3 = new JButton("b3");
GridBagConstraints gbc =new GridBagConstraints();
//gbc.insets = new Insets(1,1,1,1);
gbc.gridheight = 5;
gbc.gridwidth = 5;
gbc.weightx=15;
gbc.weighty=15;
gbc.fill = GridBagConstraints.BOTH;
p1.add(button2,gbc);
p1.add(button3,gbc);
p1.add(button1,gbc);
add(p1,BorderLayout.SOUTH);
add(p2,BorderLayout.NORTH);
EventHandler1 event1 = new EventHandler1();
button1.addActionListener(event1);
//window terminate setting
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//window size
setSize(600,400);
//pack();
//make window visible
setVisible(true);
//window title
setTitle("HCI-Projet");
//voice command
//new AePlayerWave("bin/sounds/login.wav").start();
}
public class EventHandler1 implements ActionListener
{
public void actionPerformed(ActionEvent event1) {
System.exit(0);
}
}
The problem lies the layout of your main panel. BorderLayout, which you use on that panel, has one large central area (BorderLayout.CENTER), and many smaller areas (such as NORTH and SOUTH). The layout will force anything put anywhere other than CENTER to take up the smallest amount of room possible, and max out the remaining room with what is in the CENTER area (with nothing, in this case). Since you're adding p1 as SOUTH, it keeps the vertical component of p1 as small as it can. If you add p1 as CENTER, it should fix your problem.
As a side note, if all the rows/columns in your grid will have the same height/width, you may find using GridLayout much easier than GridBagLayout.
The problem is the JPanel p1. The space of the panel is created by the standard layout, and if you just use add(p1,BorderLayout.SOUTH);, it won't change.
To make it visible you could use a Border:
p1.setBorder(BorderFactory.createLineBorder(Color.black));
Use a different layout or a GUI builder.

JTextField in the whole JFrame instead of my determined Area

yes I'm a total beginner in Java... Could somebody tell me, why the JTextField is located in the whole JFrame instead of just the space between (300,50) to (450,75) like I've inputted in setBounds?
import java.awt.*;
import javax.swing.*;
public class Chat extends JFrame {
JTextField t=new JTextField("");
public Chat() {
setVisible(true);
setSize(900, 300);
t = new JTextField();
t.setBounds(300, 50, 150, 25);
add(t);
}
}
Cause the JFrame default layout is BorderLayout and when you add the components if you don't specify it will put in the center. I recommend to use another layout like
GridBagLayout.
Example:
public Chat() {
setSize(900, 300);
t = new JTextField();
t.setPreferredSize(new Dimension(x,y));
GridBagConstraints gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 6;
gridBagConstraints.gridy = 7;
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.add(t,gridBagConstraints);
add(panel);
pack(); // this sizes the frame
setVisible(true); // call set visible after adding components
}
Should consider read this Using Layout Managers
setBounds method works with only with null Layout and default JFrame's layout is BorderLayout. Invoking JFrame's add method with BorderLayout and without specifying location defaults to BorderLayout.CENTER and centers the component, using its maximum size property as bounds. That means that setting prefered size of the component won't work with BorderLayout.CENTER. You can either change the frame's layout to null, using setLayout(null), which is considered a bad practice, because it, among other things, limits portability of the code, or use other layout manager.

Swing Components in Different Classes

probably a simple question here working on learning to make a GUI using swing and making mild headway but hit another speed bump. I am trying to keep GUI components grouped in different classes to keep my classes small and allow a more flexible GUI, but I have one component built how do I call it to my main class. Posted below is code to make the frame and the component. I would imagine there is an issue with the way I am calling but am running out of ideas on how else to call it. Any thoughts would be appreciated.....Wasn't very clear with the question trying to add the component to the JFrame in frmMainMenu, issue is that the component doesn't appear in the Frame when run currently
Main Class with JFrame
public class frmMainMenu {
public static void main(String main[]){
//Create Frame
JFrame frmMainMenu = new JFrame();
//Define Layout Manager
GridBagLayout gridBag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
frmMainMenu.setLayout(gridBag);
//Add Components
//Create Left Container
c.fill = GridBagConstraints.VERTICAL;
c.weighty = 1;
c.gridx = 0;
c.gridy = 1;
c.ipadx = 30;
frmMainMenu.add(new comLeftToolBar(),c);
frmMainMenu.setExtendedState(JFrame.MAXIMIZED_BOTH);
frmMainMenu.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//Display Frame
frmMainMenu.setVisible(true);
}
}
Component Code
public class comLeftToolBar extends JPanel{
public comLeftToolBar() {
JPanel comLeftContainer = new JPanel();
GridBagLayout leftGridBag = new GridBagLayout();
comLeftContainer.setLayout(leftGridBag);
GridBagConstraints b = new GridBagConstraints();
JToolBar comLeftToolBar = new JToolBar(JToolBar.VERTICAL);
b.gridx = 0;
b.gridy = 0;
b.ipady = 50;
JButton comNavButton = new JButton();
JButton comProButton = new JButton();
comLeftToolBar.add(comNavButton);
comLeftToolBar.add(comProButton);
comLeftContainer.add(comLeftToolBar,b);
comLeftContainer.setBorder(BorderFactory.createLineBorder(Color.black));
}
}
issue is that the component doesn't appear in the Frame when run currently
Your class is a panel. But then you create another panel (comLeftContainer) and add components to this panel. But you don't add any components to the ComLeftToolBar panel so it remains empty.
For a simple solution, at the bottom of your class you can use:
add( comLeftContainer );
Of course this is not the best solution. This will give you a structure of:
JPanel
JPanel
JToolbar
button
button
There is no need to have such a complicated structure. A toolbar is a component that be added directly to the frame.
If you want to create a class that you can add to the frame then take a look at the Swing tutorial on How to Use Tool Bars for a better structure.

Issue with JPanel as scrollable

I am developing a java JApplet to display few 10s of check boxes in scrollable pane. I included these check boxes in JPanel and added this panel on JScrollPane which is added in current ContentPane of applet. Content pane also has few other components like JTextArea, Button and Label. I would see the scroll bar but when I do scrolling, check boxes are scrolled outside of scrollpane and laid over other adjacent components. I tried setPreferredSize() with no success. What could be the issue with scrolling?
My code bites looks like:
public void init(){
contentPane = this.getContentPane();
GridBagLayout grrdbag = new GridBagLayout();
GridBagConstraints components = new GridBagConstraints();
contentPane.setLayout(gridbag);
//button, textarea and label components here
//checkboxes here
components = new GridBagConstraints();
components.anchor = GridBagConstraints.EAST;
contentPane.add(new Label("Data:", Label.RIGHT), components);
components = new GridBagConstraints();
components.gridwidth = GridBagConstraints.REMAINDER;
components.weighty = 1;
components.fill = GridBagConstraints.BOTH;
checkboxesPanel.setLayout(new BoxLayout(checkboxesPanel, BoxLayout.Y_AXIS));
conflictScrollPane = new JScrollPane(checkboxesPanel,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
contentPane.add(conflictScrollPane, components);
}
//create check boxes
public void displayboxes(){
checkboxes = new Checkbox[150];
for(int j=0;j<150;j++){
checkboxes[j] = new Checkbox("This is test data for check box here.",null,false);
checkboxesPanel.add(checkboxes[j]);
checkboxesPanel.revalidate();
}
repaint();
validate();
}
//start method
public void start() {
displayboxes();
repaint();
validate();
}
If your example is to believed, you are mixing heavy weight and light weight components. My basic recommendation is, don't. They don't play nice together.
Change your references to Checkbox to JCheckBox instead.
Check out for more info
http://java.sun.com/products/jfc/tsc/articles/mixing/
http://java-antony.blogspot.com.au/2007/07/swing-vs-awt-or-lightweight-vs.html
Shane

Categories