问题
I'm creating a GUI that should have buttons on top, a view screen in the middle, and at the bottom, an area with labels and text entry fields which change based on which button is pressed. The main panel on which everything lays is a GridBagLayout. The panel which holds the text entry fields is a CardLayout. I feel as though I've set the GridBagConstraints and everything else as it should be, but it comes up nothing as expected. I imagine there is a problem with how I've set the GridBagConstraints, or possibly an issue with sizing, but I'm not sure. I'll include a picture of what I get when I run it and what I'm trying to get.
the code:
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Container;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.text.JTextComponent;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import java.awt.GridBagLayout;
import java.util.concurrent.Executors;
import java.awt.CardLayout;
import java.awt.GridBagConstraints;
import javax.swing.JLabel;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Dimension;
import java.awt.Insets;
public class Window extends JFrame {
public Window() {
Container panel = this.getContentPane();
panel.setLayout(new GridBagLayout());
panel.setSize(1000,1000);
GridBagConstraints gbc = new GridBagConstraints();
JButton ordersButton = new JButton("Orders");
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(ordersButton, gbc);
JButton dishesButton = new JButton("Dishes");
gbc.gridx = 1;
gbc.gridy = 0;
panel.add(dishesButton, gbc);
JButton ingredientsButton = new JButton("Ingredients");
gbc.gridx = 2;
gbc.gridy = 0;
panel.add(ingredientsButton, gbc);
JButton suppliersButton = new JButton("Suppliers");
gbc.gridx = 3;
gbc.gridy = 0;
panel.add(suppliersButton, gbc);
JButton staffButton = new JButton("Staff");
gbc.gridx = 4;
gbc.gridy = 0;
panel.add(staffButton, gbc);
JButton dronesButton = new JButton("Drones");
gbc.gridx = 5;
gbc.gridy = 0;
panel.add(dronesButton, gbc);
JButton usersButton = new JButton("Users");
gbc.gridx = 6;
gbc.gridy = 0;
panel.add(usersButton, gbc);
JButton postcodesButton = new JButton("Postcodes");
gbc.gridx = 7;
gbc.gridy = 0;
panel.add(postcodesButton, gbc);
JButton configurationButton = new JButton("Configuration");
gbc.gridx = 8;
gbc.gridy = 0;
panel.add(configurationButton, gbc);
JTextField viewScreen = new JTextField();
gbc.gridy = GridBagConstraints.RELATIVE;
gbc.gridwidth = 9;
gbc.gridheight = 2;
viewScreen.setPreferredSize(new Dimension(650, 200));
panel.add(viewScreen, gbc);
JPanel ordersPanel = new JPanel();
JPanel dishesPanel = new JPanel();
ordersPanel.setLayout(new GridBagLayout());
dishesPanel.setLayout(new GridBagLayout());
ordersPanel.setSize(new Dimension(900, 500));
dishesPanel.setSize(new Dimension(900, 500));
JLabel orders1Label = new JLabel("order 1");
gbc.gridx = 0;
gbc.gridy = 0;
ordersPanel.add(orders1Label, gbc);
JLabel orders2Label = new JLabel("order 2");
gbc.gridx = 0;
gbc.gridy = 1;
ordersPanel.add(orders2Label, gbc);
JLabel dishes1Label = new JLabel("dish 1");
gbc.gridx = 0;
gbc.gridy = 0;
dishesPanel.add(dishes1Label, gbc);
JLabel dishes2Label = new JLabel("dish 2");
gbc.gridx = 0;
gbc.gridy = 1;
dishesPanel.add(dishes2Label, gbc);
JTextField orders1TextField = new JTextField();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.gridwidth = 4;
ordersPanel.add(orders1TextField, gbc);
JTextField orders2TextField = new JTextField();
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridwidth = 4;
ordersPanel.add(orders2TextField, gbc);
JTextField dishes1TextField = new JTextField();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.gridwidth = 4;
dishesPanel.add(dishes1TextField, gbc);
JTextField dishes2TextField = new JTextField();
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridwidth = 4;
dishesPanel.add(dishes2TextField, gbc);
orders1TextField.setPreferredSize(new Dimension(400, 20));
orders2TextField.setPreferredSize(new Dimension(400, 20));
dishes1TextField.setPreferredSize(new Dimension(400, 20));
dishes2TextField.setPreferredSize(new Dimension(400, 20));
JPanel entryFields = new JPanel();
CardLayout c1 = new CardLayout();
entryFields.setLayout(c1);
entryFields.setSize(new Dimension(900, 600));
gbc.gridheight = 7;
gbc.gridwidth = 9;
gbc.weighty = 1;
gbc.gridy = GridBagConstraints.RELATIVE;
entryFields.add("ordersPanel",ordersPanel);
entryFields.add("dishesPanel", dishesPanel);
c1.show(entryFields, "ordersPanel");
panel.add(entryFields, gbc);
ordersButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
c1.show(entryFields, "ordersPanel");
}
});
dishesButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
c1.show(entryFields, "dishesPanel");
}
});
//Display window
setSize(800,600);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
Window win = new Window();
}
}
what appears:
what i want:
I should add that the following picture is what I get before I resize the window to the size of my computer's screen. You can see the label, here, though you can't in the full size version, and they are clumped together, so possibly it's an issue with the way I set my weightings, I just made it so at least every row and column had at least one component with a weighting of 1.
回答1:
Well let's start of by saying that whatever modification you make to your GridBagConstraints
instance is persisted to any of the following usages of that instance.
So if you do this gbc.gridwidth = 9
make sure to reset it to gbc.gridwidth = 1
, otherwise every element added will have a gridwidth of 9 applied to it.
And no need to set gridy = 0
everytime you add a button on the same line, that just adds unnecessary lines of code.
Now I have just cleaned up your Window()
code to show you a correct use of the GridBagConstraints
and removed the duplicate assigns.
You will have to add your ActionListeners
again
public Window() {
Container panel = this.getContentPane();
panel.setLayout(new GridBagLayout());
panel.setSize(1000,1000);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridy = 0; // First row
JButton ordersButton = new JButton("Orders");
gbc.gridx = 0;
panel.add(ordersButton, gbc);
JButton dishesButton = new JButton("Dishes");
gbc.gridx = 1;
panel.add(dishesButton, gbc);
JButton ingredientsButton = new JButton("Ingredients");
gbc.gridx = 2;
panel.add(ingredientsButton, gbc);
JButton suppliersButton = new JButton("Suppliers");
gbc.gridx = 3;
panel.add(suppliersButton, gbc);
JButton staffButton = new JButton("Staff");
gbc.gridx = 4;
panel.add(staffButton, gbc);
JButton dronesButton = new JButton("Drones");
gbc.gridx = 5;
panel.add(dronesButton, gbc);
JButton usersButton = new JButton("Users");
gbc.gridx = 6;
panel.add(usersButton, gbc);
JButton postcodesButton = new JButton("Postcodes");
gbc.gridx = 7;
panel.add(postcodesButton, gbc);
JButton configurationButton = new JButton("Configuration");
gbc.gridx = 8;
panel.add(configurationButton, gbc);
JTextField viewScreen = new JTextField();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 9;
viewScreen.setPreferredSize(new Dimension(650, 200));
viewScreen.setMinimumSize(new Dimension(650, 200));
panel.add(viewScreen, gbc);
gbc.gridwidth = 1; // Reset the gridwidth
// Third row
JLabel orders1Label = new JLabel("order 1");
gbc.gridx = 1;
gbc.gridy = 2;
panel.add(orders1Label, gbc);
JLabel orders2Label = new JLabel("order 2");
gbc.gridx = 1;
gbc.gridy = 3;
panel.add(orders2Label, gbc);
JLabel dishes1Label = new JLabel("dish 1");
gbc.gridx = 1;
gbc.gridy = 4;
panel.add(dishes1Label, gbc);
JLabel dishes2Label = new JLabel("dish 2");
gbc.gridx = 1;
gbc.gridy = 5;
panel.add(dishes2Label, gbc);
gbc.gridwidth = 4; // Textfield width
JTextField orders1TextField = new JTextField();
gbc.gridx = 2;
gbc.gridy = 2;
panel.add(orders1TextField, gbc);
JTextField orders2TextField = new JTextField();
gbc.gridx = 2;
gbc.gridy = 3;
panel.add(orders2TextField, gbc);
JTextField dishes1TextField = new JTextField();
gbc.gridx = 2;
gbc.gridy = 4;
panel.add(dishes1TextField, gbc);
JTextField dishes2TextField = new JTextField();
gbc.gridx = 2;
gbc.gridy = 5;
panel.add(dishes2TextField, gbc);
orders1TextField.setPreferredSize(new Dimension(400, 20));
orders2TextField.setPreferredSize(new Dimension(400, 20));
dishes1TextField.setPreferredSize(new Dimension(400, 20));
dishes2TextField.setPreferredSize(new Dimension(400, 20));
//Display window
setSize(800,600);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
And I got this layout
The layout is probably not exactly what you wanted, but I hope you can continue your work with this example. ;)
回答2:
Consider breaking the design into smaller, easier to layout containers.
It makes a clear and simple code, and allows for high flexibility:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Window extends JFrame {
public Window() {
Container panel = this.getContentPane(); //uses Borderlayout by default
JPanel buttonsPane = new JPanel(new GridLayout(1, 0));
JButton ordersButton = new JButton("Orders");
buttonsPane.add(ordersButton);
JButton dishesButton = new JButton("Dishes");
buttonsPane.add(dishesButton);
JButton ingredientsButton = new JButton("Ingredients");
buttonsPane.add(ingredientsButton);
JButton suppliersButton = new JButton("Suppliers");
buttonsPane.add(suppliersButton);
JButton staffButton = new JButton("Staff");
buttonsPane.add(staffButton);
JButton dronesButton = new JButton("Drones");
buttonsPane.add(dronesButton);
JButton usersButton = new JButton("Users");
buttonsPane.add(usersButton);
JButton postcodesButton = new JButton("Postcodes");
buttonsPane.add(postcodesButton);
JButton configurationButton = new JButton("Configuration");
buttonsPane.add(configurationButton);
panel.add(buttonsPane, BorderLayout.PAGE_START); //add to top
JTextField viewScreen = new JTextField();
viewScreen.setPreferredSize(new Dimension(650, 200));
panel.add(viewScreen, BorderLayout.CENTER); //add to center
JPanel ordersList = new JPanel();
ordersList.setLayout(new BoxLayout(ordersList, BoxLayout.Y_AXIS));
JPanel ordersPanel = new JPanel(); //uses FlowLayout by default
ordersList.add(ordersPanel);
JLabel orders1Label = new JLabel("order 1");
ordersPanel.add(orders1Label);
JTextField orders1TextField = new JTextField(50);
ordersPanel.add(orders1TextField);
JPanel ordersPanel1 = new JPanel();
ordersList.add(ordersPanel1);
JLabel orders2Label = new JLabel("order 2");
ordersPanel1.add(orders2Label);
JTextField orders2TextField = new JTextField(50);
ordersPanel1.add(orders2TextField);
JPanel dishesList = new JPanel();
dishesList.setLayout(new BoxLayout(dishesList, BoxLayout.Y_AXIS));
JPanel dishesPanel = new JPanel();
dishesList.add(dishesPanel);
JLabel dishes1Label = new JLabel("dish 1");
dishesPanel.add(dishes1Label);
JTextField dishes1TextField = new JTextField(50);
dishesPanel.add(dishes1TextField);
JPanel dishesPanel1 = new JPanel();
dishesList.add(dishesPanel1);
JLabel dishes2Label = new JLabel("dish 2");
dishesPanel1.add(dishes2Label);
JTextField dishes2TextField = new JTextField(50);
dishesPanel1.add(dishes2TextField);
JPanel entryFields = new JPanel();
CardLayout c1 = new CardLayout();
entryFields.setLayout(c1);
entryFields.add("ordersPanel",ordersList);
entryFields.add("dishesPanel", dishesList);
c1.show(entryFields, "ordersPanel");
panel.add(entryFields,BorderLayout.PAGE_END);
ordersButton.addActionListener(arg0 -> c1.show(entryFields, "ordersPanel"));
dishesButton.addActionListener(arg0 -> c1.show(entryFields, "dishesPanel"));
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(()->new Window());
}
}
来源:https://stackoverflow.com/questions/54924563/gridbaglayout-not-coming-out-as-expected