I'm trying to create a GridBagLayout, I have got the panels set out exactly how I want them. However I cannot set the background colour of each panel without also forcing all of the components to center.
Here the panels are coloured but all of the components center
http://i.imgur.com/BattBdw.png
Here all of the components snap to NORTHWEST as specified in the code but the background color does not fill the pane.
http://i.imgur.com/lvuEy4u.png
Sorry I cannot embed the pictures, my reputation is not high enough :(
GridBagConstraints GBC = new GridBagConstraints();
GBC.fill = GridBagConstraints.BOTH;
GBC.anchor = GridBagConstraints.NORTHWEST;
//green panel
GBC.gridx = 0;
GBC.gridy = 0;
GBC.weightx = 0.1;
GBC.weighty = 0.1;
JPanel panelGreen = new JPanel();
panelGreen.setBackground(Color.green);
//add button to green panel
JButton button = new JButton("Button");
panelGreen.add(button, GBC);
contentPane.add(panelGreen, GBC);
//blue panel
GBC.gridx = 1;
GBC.gridy = 0;
GBC.weighty = 0.1;
GBC.weightx = 0.9;
JPanel panelBlue = new JPanel();
panelBlue.setBackground(Color.blue);
contentPane.add(panelBlue, GBC);
//red panel
GBC.gridx = 0;
GBC.gridy = 1;
GBC.weighty = 0.8;
GBC.weightx = 0.1;
JPanel panelRed = new JPanel();
panelRed.setBackground(Color.red);
contentPane.add(panelRed, GBC);
//black panel
GBC.gridx = 0;
GBC.gridy = 2;
GBC.weighty = 0.1;
GBC.weightx = 0.1;
GBC.gridwidth =2;
JPanel panelBlack = new JPanel();
panelBlack.setBackground(Color.black);
contentPane.add(panelBlack, GBC);
//yellow panel
GBC.gridx = 1;
GBC.gridy = 1;
GBC.weighty = 0.8;
GBC.weightx = 0.9;
GBC.gridwidth =1;
JPanel panelYellow = new JPanel();
panelYellow.setBackground(Color.yellow);
contentPane.add(panelYellow, GBC);
Firstly, creating a JPanel() with the default constructor means it gets a FlowLayout - you need to tell your panels to use GridBagLayouts:
JPanel panelGreen = new JPanel(new GridBagLayout());
Other than that, you just need to have the "fill" property set to NONE when you add your JButton or it will expand to fill the whole pane. After you've added the button you can set it to BOTH for the panels themselves:
GBC.fill = GridBagConstraints.NONE;
JButton button = new JButton("Button");
panelGreen.add(button, GBC);
GBC.fill = GridBagConstraints.BOTH;
contentPane.add(panelGreen, GBC);
Related
My programs user interface currently uses a grid bag layout, I want it to be a fixed size however when i upload a picture to the label the whole interface changes in dimensions.
Below is code for my layout manager
public SearchService() throws Exception {
setSize(600, 600);
setResizable(false);
JPanel mainPanel = new JPanel();
JPanel templatePanel = new JPanel();
JPanel toolPanel = new JPanel();
JLabel picLabel = new JLabel();
JLabel tools = new JLabel("Tools");
JLabel templates = new JLabel("Templates");
JButton upload = new JButton("Upload");
JButton search = new JButton("Search");
JButton save = new JButton("Save");
//Main panel
GridBagLayout GBPanel = new GridBagLayout();
GridBagConstraints GBC = new GridBagConstraints();
mainPanel.setLayout( GBPanel );
//Template panel
GBC.gridx = 0;
GBC.gridy = 0;
GBC.gridwidth = 1;
GBC.gridheight = 3;
GBC.fill = GridBagConstraints.BOTH;
GBC.weightx = 1;
GBC.weighty = 0;
GBC.anchor = GridBagConstraints.WEST;
GBPanel.setConstraints( leftPanel, GBC );
leftPanel.add(templates);
mainPanel.add( leftPanel );
//Picture label
GBC.gridx = 1;
GBC.gridy = 0;
GBC.gridwidth = 2;
GBC.gridheight = 1;
GBC.fill = GridBagConstraints.BOTH;
GBC.weightx = 0;
GBC.weighty = 1;
GBC.anchor = GridBagConstraints.CENTER;
GBPanel.setConstraints( picLabel, GBC );
mainPanel.add( picLabel );
//Tool panel
GBC.gridx = 4;
GBC.gridy = 0;
GBC.gridwidth = 1;
GBC.gridheight = 3;
GBC.fill = GridBagConstraints.BOTH;
GBC.weightx = 1;
GBC.weighty = 0;
GBC.anchor = GridBagConstraints.EAST;
GBPanel.setConstraints( rightPanel, GBC );
rightPanel.add(tools);
mainPanel.add( rightPanel );
//Upload button
GBC.gridx = 1;
GBC.gridy = 1;
GBC.gridwidth = 1;
GBC.gridheight = 1;
GBC.fill = GridBagConstraints.BOTH;
GBC.weightx = 1;
GBC.weighty = 0;
GBC.anchor = GridBagConstraints.PAGE_START;
GBPanel.setConstraints( upload, GBC );
mainPanel.add( upload );
//Save button
GBC.gridx = 2;
GBC.gridy = 1;
GBC.gridwidth = 1;
GBC.gridheight = 1;
GBC.fill = GridBagConstraints.BOTH;
GBC.weightx = 1;
GBC.weighty = 0;
GBC.anchor = GridBagConstraints.PAGE_START;
GBPanel.setConstraints( save, GBC );
mainPanel.add( save );
//Search button
GBC.gridx = 1;
GBC.gridy = 2;
GBC.gridwidth = 2;
GBC.gridheight = 1;
GBC.fill = GridBagConstraints.BOTH;
GBC.weightx = 1;
GBC.weighty = 0;
GBC.anchor = GridBagConstraints.PAGE_START;
GBPanel.setConstraints( search, GBC );
mainPanel.add( search );
add(mainPanel);
and below is code that adds the picture
upload.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser("C:\\Users);
FileNameExtensionFilter filter = new FileNameExtensionFilter("Image", "jpg", "png", "bmp");
chooser.setFileFilter(filter);
int result = chooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = chooser.getSelectedFile();
BufferedImage bi;
userPhoto = chooser.getSelectedFile().getPath();
try {
bi = ImageIO.read(selectedFile);
Image dimg = bi.getScaledInstance(picLabel.getWidth(), picLabel.getHeight(), Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(dimg));
}
catch(IOException IOe) {
IOe.printStackTrace();
}
System.out.println(userPhoto);
}
}
});
I' ve added two photos to show the results with my program. This is how it looks when i first run and how i want the layout to stay
and this is how layout looks after uploading an image
as you can see the left and right panels get shrunk and the picture doesn't even take up the whole picture label.
I also added this line System.out.println(picLabel.getWidth()); in the action listener and saw that when the button is first hit the size is set to 299 but if i hit the button again it changes and does so for each time. I want to know if its possible to make the image stay at a width of 299.
GBC.gridwidth = 5;
GBC.gridheight = 20
You can't just randomly assign gridwith/height to a component. You actually need 20 other components if you want to component to span the same height as the other components.
as you can see the left and right panels get shrunk and the picture doesn't even take up the whole picture label.
If you don't want the layout to change then use a different layout manager or nested panels with different layout managers.
For example you start with the BorderLayout.
Then you can add panels to the LINE_START and LINE_END.
Then you need another panel in the CENTER. Again you could use a BorderLayout. You add your picture to the CENTER and then another panel with the buttons at the PAGE_END.
Now all the components except the image are fixed in size. The space available to the image will vary depending on the size of the frame.
So the basic code is:
JPanel buttonPanel = new JPanel(...);
JLabel image = new JLabel(...);
JPanel center = new JPanel( new BorderLayout() );
center.add(image, BorderrLayout.CENTER);
center.add(buttonPanel, BorderLayout.PAGE_END);
JPanel leftPanel = new JPanel(...);
JPanel rightPanel = new JPanel(...);
frame.add(leftPanel, BorderLayout.LINE_START);
frame.add(center, BorderLayout.CENTER);
frame.add(rightPanel, BorderLayout.LINE_END);
Far less confusing than trying to play with all the constraints of the GridBagLayout.
Now the child panels (left, right, buttons) can use appropriate layout managers.
I was wondering how to center my components, I found the gridBagLayout but I couldn't find a way to have it bigger than it is : my buttons are too small.
Part of my code :
private void addMainButtons() {
JPanel container = new JPanel() {
private static final long serialVersionUID = -424395301619105440L;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension dim = this.getSize();
DateFormat format = new SimpleDateFormat("dd/MM/yyyy");
Date date = new Date();
g.setFont(new Font("TimesRoman", Font.PLAIN, 20));
g.setColor(Color.BLACK);
String s = format.format(date);
g.drawString(s, (int) ((dim.getWidth() - s.length() - 80) / 2), 20);
}
};
container.setBackground(new Color(109, 69, 60));
JButton productsButton = new JButton("Produits");
productsButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cl.show(frame, pages[1]);
}
});
productsButton.setAlignmentY(Component.CENTER_ALIGNMENT);
productsButton.setAlignmentX(Component.CENTER_ALIGNMENT);
// Creating grid
container.setPreferredSize(new Dimension(400, 600));
container.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
container.add(productsButton, gbc);
gbc.gridy = 1;
gbc.gridwidth = 1;
container.add(new JButton("Entrée"), gbc);
gbc.gridx = 1;
container.add(new JButton("Sortie"), gbc);
mainPage.setLayout(new BorderLayout());
mainPage.add(container, BorderLayout.CENTER);
// End of main page
}
GridBagLayout is really difficult to use, is there another way to center components ? I could use NestedLayouts but I don't know how.
You can use weightx and/or weighty to effect the amount of space the components will occupy, for example, if I do
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.weightx = 1;
gbc.weighty = 1;
container.add(productsButton, gbc);
gbc.gridy = 1;
gbc.gridwidth = 1;
container.add(new JButton("Entrée"), gbc);
gbc.gridx = 1;
container.add(new JButton("Sortie"), gbc);
I can generate this...
You could use two containers, one holding a JLabel which shows the date and one which contains the buttons, but I doubt that's what you're really after.
You can use ipadx and ipady which adds the amount to the components preferred size
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.ipadx = 40;
gbc.ipady = 40;
container.add(productsButton, gbc);
gbc.gridy = 1;
gbc.gridwidth = 1;
container.add(new JButton("Entrée"), gbc);
gbc.gridx = 1;
container.add(new JButton("Sortie"), gbc);
which, when included with your existing constraints, allows you to "grow" the buttons a bit.
Try below code for increasing size of button while adding every components to gridbagconstraints. Change the value of weightx/weighty as you want.
gbc.weightx = 1.0;
gbc.weighty = 1.0;
To give more spaces between components, use below code while adding every components to gridbagconstraints.
gbc.insets = new Insets(2, 2, 2, 2);
According to my knowledge, you used correct way to center components. It can also be done by other layout but it may be little bit difficult.
My form is very simple I just want to have labels next to text fields. The labels are default centering and it makes the form look weird. I want to the labels exactly next to the textfield. I have played with the horizontal alignment of the labels and textfields but it did not change anything.
Here is my code:
JPanel root = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets= new Insets(0,0,0,0);
newVehicleRecord.setLayout(new BorderLayout());
newVehicleRecord.add(root,BorderLayout.PAGE_START);
JLabel title = new JLabel("New Vehicle Record - Customer ID:" + customerIDInfo.getText());
title.setFont(fontTitle);
gbc.weightx = 0;
gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth= 2;
root.add(title,gbc);
gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth= 1;
root.add(Box.createVerticalStrut(15),gbc);
gbc.gridx = 0; gbc.gridy = 2;
JLabel classificationLabel = new JLabel("Classification:");
classificationLabel.setHorizontalAlignment(JLabel.RIGHT);
root.add(classificationLabel,gbc);
gbc.gridx = 1; gbc.gridy = 2;
JTextField classificationTextField = new JTextField(10);
classificationTextField.setHorizontalAlignment(JTextField.LEFT);
root.add(classificationTextField,gbc);
gbc.gridx = 0; gbc.gridy = 3;
JLabel modelLabel = new JLabel("Model:");
root.add(modelLabel,gbc);
gbc.gridx = 1; gbc.gridy = 3;
JTextField modelTextField = new JTextField(10);
root.add(modelTextField,gbc);
gbc.gridx = 0; gbc.gridy = 4;
JLabel makeLabel = new JLabel("Make:");
root.add(makeLabel,gbc);
gbc.gridx = 1; gbc.gridy = 4;
JTextField makeTextField = new JTextField(10);
root.add(makeTextField,gbc);
I get the following display: http://prntscr.com/6j3iki
As you can see there is a lot of empty space between the label and the textfield which I don't want.
I want to the labels exactly next to the textfield.
You need to play with the anchor constraint:
gbc.anchor = GridBagConstraints.LINE_END;
panel.add(label, gbc);
gbc.anchor = GridBagConstraints.LINE_START;
panel.add(textField, gbc);
Also you would probably want something like:
gbc.insets = new Insets(5, 10, 5, 10);
so the right edge of the label has some space between the left edge of the text field.
Read the section from the Swing tutorial on How to Use GridBagLayout for more information on all the constraints.
Something like this:
gbc.gridx = 0; gbc.gridy = 3;
gbc.anchor = GridBagConstraints.EAST;
JLabel modelLabel = new JLabel("Model:");
root.add(modelLabel,gbc);
So you need to add the line
gbc.anchor = GridBagConstraints.EAST;
to each your label.
Another possibility:
gbc.gridx = 0; gbc.gridy = 3;
gbc.fill = GridBagConstraints.HORIZONTAL;
JLabel modelLabel = new JLabel("Model:");
modelLabel.setHorizontalAlignment(SwingConstants.RIGHT);
root.add(modelLabel,gbc);
I want to create an application with buttons arrayed into invisible table. The buttons should fill all the available space inside the imaginary cells even when I´ll resize the frame. I´m using Swing, GridBagLayout. I've read some articles and the solution was to add .weightx=1 and .weighty=1. Weightx works perfect and it fill the gaps but weighty doesn't. Buttons don´t extend into height of cell. Is there a problem with my code or is there something to add that solve my problem? Or should I use absolutely another layout?
public class NewClass {
public void NewClass(){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
GridBagLayout layout = new GridBagLayout();
panel.setLayout(layout);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridx = 0;
gbc.gridy = 0;
JButton B11 = new JButton("11");
panel.add(B11,gbc);
gbc.gridx = 1;
gbc.gridy = 0;
JButton B12 = new JButton("12");
panel.add(B12,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
JButton B21 = new JButton("21");
panel.add(B21,gbc);
gbc.gridx = 1;
gbc.gridy = 1;
JButton B22 = new JButton("22");
panel.add(B22,gbc);
frame.pack();
frame.setSize(800,400);
frame.setVisible(true);
}}
You're using the wrong GridBagConstraints#fill field value, since the value you're using is telling the layout manager to fill the buttons horizontally only.
You need to change
gbc.fill = GridBagConstraints.HORIZONTAL;
to
// gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.fill = GridBagConstraints.BOTH;
if you want the buttons to fill both directions, both horizontally and vertically.
I have a TabbedPane inside of which there are Panels.
I am dealing now with the first panel.
Inside this panel there should be another small panel on the left(I just placed a textfield instead for reference) a textarea in the center and below it a row of buttons. But the buttons are placed far too low below from the textarea. Besides, if I resize the frame, the textarea just goes away, vanishes. The textfield is set ok, top left, the textarea more or less yes in the center, but it should not go away when resizing (it would make a weird effect for the user).
I have tried all variants south, west, whatever, no changes or it goes up too far anyways.
I have read somewhat similar questions but I dont see how their answers solve my case.
So, here is the code:
super("Proyecto");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(1200, 800);
/* 1. CREATE PANEL*/
/*MAIN PANEL BOOK READER*/
JPanel panelbookreader = new JPanel();
/*CREATE TEXTAREA*/
JTextArea areatextobookreader = new JTextArea(20, 80);
/* 2. ADD THAT COMPONENT TO ITS PARENT*/
panelbookreader.add(areatextobookreader);
/* 3. SET A LAYOUT FOR THE PANEL THAT WILL ORGANIZE COMPONENTS INSIDE*/
panelbookreader.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
JTextField hold = new JTextField(20);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
panelbookreader.add(hold, gbc);
//TEXT AREA
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 0;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.CENTER;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
panelbookreader.add(areatextobookreader, gbc);
//BUTTONS
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.SOUTH;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
panelbookreader.add(openbook, gbc);
/*ADD THE PARENT TO ITS PARENT OR TO GRANPARENT OF COMPONENT*/
JTabbedPane tabulado = new JTabbedPane();
tabulado.addTab("BOOK READER",panelbookreader);
Your weightx for JTextArea is 1.0 which is fine.
But when you specify weighty also as 1.0, then there is no space for JButton. Make some changes in weighty of textarea and also specify weighty for jbutton.