简体   繁体   中英

JTextField only shows a slit with GridBagLayout, solutions i found for similar problems didnt work

So have a JFrame which contains 2 JPanels and one Button using the GridBagLayout. But the problem lies with the Panels which also use GridBagLayouts. JPanel p_addIng has has a 3x2 Grid with two JTextFields in the first column one the the size of the first is fine but the second one is way too thin.

Some disclaimers ahead: ing stands for ingredient, gbc for GridBagConstraints, everything with b_var means its a swing component b = JButton, tf = JTextField, p = JPanel, cb = JCombobox.

What i've already tried because of other posts: gbc_addIng.fill = GridBagConstraints.HORIZONTAL; gbc_addIng.weightx = 1; gbc_addIng.fill = GridBagConstraints.HORIZONTAL; gbc_addIng.weightx = 1; i saw also somewhere to use the pack() method but this was for the JFrame and didn't do anything to fix the problem. Here's the code:

//making a new panel
//initializing the new Panel
p_addIng = new JPanel();
p_addIng.setName("Adding an Ingredient");
p_addIng.setPreferredSize(ingPanelDim);
p_addIng.setLayout(new GridBagLayout());
GridBagConstraints gbc_ing = new GridBagConstraints(0, 0, 1, 1, 1, 0,
                                                    GridBagConstraints.CENTER, GridBagConstraints.BOTH
                                                    new Insets(0,0,0,0),10, 10);

//the components of the panel
//TextField to set the name of the Ingredient
gbc_ing.gridx = 0; //the position of the component on the panel
gbc_ing.gridy = 0;
tf_ingName = new JTextField();
tf_ingName.setPreferredSize(new Dimension(ingPanelDim.width / 2, ingPanelDim.height/2));
tf_ingName.addActionListener(this);
p_addIng.add(tf_ingName, gbc_ing); //adding the component to the Panel
//endOfTextFieldIngName
gbc_ing.gridx = 1;
gbc_ing.gridy = 0;
//button to add the ingredient
tf_amnt = new JTextField("Choose amount");
tf_amnt.setPreferredSize(new Dimension(ingPanelDim.width/4, ingPanelDim.height/2));
tf_amnt.addActionListener(this);
p_addIng.add(tf_amnt, gbc_ing);
//endOfButtonToAddIng
//button to add the ingredient
gbc_ing.gridx = 2;
gbc_ing.gridy = 0;
UnitOfMeasurement[] un = {UnitOfMeasurement.g, UnitOfMeasurement.kg, UnitOfMeasurement.Stück, UnitOfMeasurement.L, UnitOfMeasurement.ml, UnitOfMeasurement.cm};
cb_measurement = new JComboBox<UnitOfMeasurement>(un);
cb_measurement.setPreferredSize(new Dimension(ingPanelDim.width/4, ingPanelDim.height/2));
cb_measurement.addActionListener(this);
p_addIng.add(cb_measurement, gbc_ing);
//endOfButtonToAddIng
//button to add the ingredient
gbc_ing.gridx = 0;
gbc_ing.gridy = 1;
b_addIng = new JButton("Add Ingredient");
b_addIng.setPreferredSize(new Dimension(ingPanelDim.width/2, ingPanelDim.height/2));
b_addIng.addActionListener(this);
p_addIng.add(b_addIng, gbc_ing);
//endOfButtonToAddIng
//button to remove the ingredient
gbc_ing.gridx = 2;
gbc_ing.gridy = 1;
b_removeIng = new JButton("Remove Ingredient");
b_removeIng.setPreferredSize(new Dimension(ingPanelDim.width/2, ingPanelDim.height/2));
b_removeIng.addActionListener(this);
p_addIng.add(b_removeIng, gbc_ing);
//endOfButtonToRemoveIng
//
frame.pack();
frame.add(p_addIng,gbc_frame);
//

Here,as wished, is the fully functional class the only thing thats missing is the enumeration UnitOfMeasurement which contains the elements as shown in the list for cb_meausrement:


package WindowDesign;

import Food.UnitOfMeasurement;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;

public class StartingWindow implements ActionListener {

    //window dimension
    private static final int WIDTH = 500;
    private static final int HEIGHT = 200;
    //

    //the JFrame
    private JFrame frame;
    //JComponents
    //adding an Ingredient
    private JPanel p_addIng;
    private Dimension ingPanelDim = new Dimension(WIDTH/2, HEIGHT/2);
    private JButton b_addIng; //a button to add an Ingredient
    private JButton b_removeIng;
    private JTextField tf_ingName;
    private JTextField tf_amnt;
    private JComboBox<UnitOfMeasurement> cb_measurement;
    //

    //adding a Recipe
    private JPanel p_addRecipe;
    private JButton b_addRecipe;    // add a Recipe to the list of Recipes
    private JButton b_removeRecipe;
    private JButton b_buildRecipe;
    private JButton b_clearRecipe;
    private JTextField tf_recipeName;
    private JTextField tf_ingredient;
    private JComboBox<UnitOfMeasurement> cb_measurementR;
    //

    //

    private JButton b_findCombination; //find the right combination of things to buy
    private JButton b_exit; //exit the program

    public StartingWindow(String name) {
        frame = new JFrame(name);
        frame.setLayout(new GridBagLayout());
        //constraints
        GridBagConstraints gbc_frame = new GridBagConstraints();
        frame.setSize(WIDTH, HEIGHT);
        frame.setBackground(Color.LIGHT_GRAY);
        gbc_frame.ipadx = 10;
        gbc_frame.ipady = 10;
        gbc_frame.weightx = 1;
        gbc_frame.fill = GridBagConstraints.BOTH;
        //Adding the Panels
        gbc_frame.gridx = 0;
        gbc_frame.gridy = 0;
        implementIngredientPanel(gbc_frame);

        gbc_frame.gridx += 1;
        gbc_frame.gridy = 0;
        implementRecipePanel(gbc_frame);
        //

        gbc_frame.gridx = 0;
        gbc_frame.gridy = 1;
        implementStartingPanel(gbc_frame);

        /*



        b_exit = new JButton("exit");
        b_exit.addActionListener(this);

         */

        /*
        frame.add(b_findCombination);
        frame.add(b_addIng);
        frame.add(b_addRecipe);
        frame.add(b_exit);
         */

        frame.setResizable(false);
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.requestFocus();
        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setVisible(true);

    }
    //helper function to organize code
    private void implementIngredientPanel(GridBagConstraints gbc_frame){
        //making a new panel
        //initializing the new Panel
        p_addIng = new JPanel();
        p_addIng.setName("Adding an Ingredient");
        p_addIng.setPreferredSize(ingPanelDim);
        p_addIng.setLayout(new GridBagLayout());
        GridBagConstraints gbc_ing = new GridBagConstraints(0, 0, 1, 1, 1, 0,
                                                            GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                                                            new Insets(0,0,0,0),10, 10);

        //the components of the panel
        //TextField to set the name of the Ingredient
        gbc_ing.gridx = 0; //the position of the component on the panel
        gbc_ing.gridy = 0;
        tf_ingName = new JTextField();
        tf_ingName.setPreferredSize(new Dimension(ingPanelDim.width / 2, ingPanelDim.height/2));
        tf_ingName.addActionListener(this);
        p_addIng.add(tf_ingName, gbc_ing); //adding the component to the Panel
        //endOfTextFieldIngName
        gbc_ing.gridx = 1;
        gbc_ing.gridy = 0;
        //button to add the ingredient
        tf_amnt = new JTextField("Choose amount");
        tf_amnt.setPreferredSize(new Dimension(ingPanelDim.width/4, ingPanelDim.height/2));
        tf_amnt.addActionListener(this);
        p_addIng.add(tf_amnt, gbc_ing);
        //endOfButtonToAddIng
        //button to add the ingredient
        gbc_ing.gridx = 2;
        gbc_ing.gridy = 0;
        UnitOfMeasurement[] un = {UnitOfMeasurement.g, UnitOfMeasurement.kg, UnitOfMeasurement.Stück, UnitOfMeasurement.L, UnitOfMeasurement.ml, UnitOfMeasurement.cm};
        cb_measurement = new JComboBox<UnitOfMeasurement>(un);
        cb_measurement.setPreferredSize(new Dimension(ingPanelDim.width/4, ingPanelDim.height/2));
        cb_measurement.addActionListener(this);
        p_addIng.add(cb_measurement, gbc_ing);
        //endOfButtonToAddIng
        //button to add the ingredient
        gbc_ing.gridx = 0;
        gbc_ing.gridy = 1;
        b_addIng = new JButton("Add Ingredient");
        b_addIng.setPreferredSize(new Dimension(ingPanelDim.width/2, ingPanelDim.height/2));
        b_addIng.addActionListener(this);
        p_addIng.add(b_addIng, gbc_ing);
        //endOfButtonToAddIng
        //button to remove the ingredient
        gbc_ing.gridx = 2;
        gbc_ing.gridy = 1;
        b_removeIng = new JButton("Remove Ingredient");
        b_removeIng.setPreferredSize(new Dimension(ingPanelDim.width/2, ingPanelDim.height/2));
        b_removeIng.addActionListener(this);
        p_addIng.add(b_removeIng, gbc_ing);
        //endOfButtonToRemoveIng
        //
        frame.pack();
        frame.add(p_addIng,gbc_frame);
        //
    }

    private void implementRecipePanel(GridBagConstraints gbc_frame){
        //Adding a Panel to add
        p_addRecipe = new JPanel();
        p_addRecipe.setName("Adding an Ingredient");
        p_addRecipe.setPreferredSize(new Dimension(WIDTH/2, HEIGHT/2));
        p_addRecipe.setLayout(new GridBagLayout());
        GridBagConstraints gbc_recipe = new GridBagConstraints();


        //the components:
        //add Button to Add a Recipe
        b_addRecipe = new JButton("Add Recipe");
        b_addRecipe.addActionListener(this);
        p_addRecipe.add(b_addRecipe, gbc_recipe );
        //

        frame.add(p_addRecipe, gbc_frame);
    }

    private void implementStartingPanel(GridBagConstraints c){
        b_findCombination = new JButton("go shopping!");
        b_findCombination.addActionListener(this);
        c.fill = GridBagConstraints.HORIZONTAL;

        frame.add(b_findCombination, c);
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {

    }
}

Here is a working example that may or may not be what you're asking for...

package stackoverflow;

import javax.swing.*;
import java.awt.*;

public class IngredientJFrame {

    public static void main(String... args) {

        IngredientJFrame ingredientJFrame = new IngredientJFrame();
        ingredientJFrame.init();
    }

    public void init() {

        JFrame jFrame = new JFrame();

        //making a new panel
        //initializing the new Panel
        JPanel p_addIng = new JPanel();
        p_addIng.setLayout(new GridBagLayout());

        GridBagConstraints gbc_ing = new GridBagConstraints();

        JLabel l_addIng = new JLabel("Add Ingredient");
        gbc_ing.gridx = 0;
        gbc_ing.gridy = 0;
        p_addIng.add(l_addIng, gbc_ing);

        JTextField tf_ingName = new JTextField();
        gbc_ing.gridx = 1;
        gbc_ing.gridy = 0;
        gbc_ing.fill = GridBagConstraints.HORIZONTAL;
        p_addIng.add(tf_ingName, gbc_ing); //adding the component to the Panel

        JLabel tf_amnt = new JLabel("Choose amount");
        gbc_ing.gridx = 0;
        gbc_ing.gridy = 1;
        gbc_ing.fill = GridBagConstraints.NONE;
        p_addIng.add(tf_amnt, gbc_ing);

        JComboBox cb_measurement = new JComboBox();
        gbc_ing.gridx = 1;
        gbc_ing.gridy = 1;
        gbc_ing.fill = GridBagConstraints.HORIZONTAL;
        p_addIng.add(cb_measurement, gbc_ing);

        JButton b_addIng = new JButton("Add Ingredient");
        gbc_ing.gridx = 0;
        gbc_ing.gridy = 2;
        gbc_ing.fill = GridBagConstraints.NONE;
        p_addIng.add(b_addIng, gbc_ing);

        JButton b_removeIng = new JButton("Remove Ingredient");
        gbc_ing.gridx = 1;
        gbc_ing.gridy = 2;
        p_addIng.add(b_removeIng, gbc_ing);

        jFrame.pack();
        jFrame.add(p_addIng);
        jFrame.setSize(500, 500);
        jFrame.setVisible(true);
    }
}

GridBayLayout (GBL) and GridBagConstraints (GBC) are powerful, but hard to use properly, and easy to screw up.

Here are some pointers on how I use to use these two classes and other tips for making a Swing based UI:

  • Text, in general, should be displayed using a JLabel. That should help right away with your formatting.
  • In general with GBL and GBC we don't normally set actual sizes on our components. We allow the components to react to one another and fill the space as needed. Often times using JPanels inside of other JPanels to get the correct flow that we are looking for.
  • The way that I use GBC is most likely not great, but I hate having to remake that object over and over and over and over again. So, I reused it in my example, you just have to be careful when reusing that object because it is easy to set one particular field and forget to 'unset' it later. Thing insets.
  • Typically a component has an anonymous inner class that actually does the listening to the component.

but the second one is way too thin.

When using a GridBagLayout when a component can't be displayed at its preferred size, then then it is displayed at its minimum size. The minimum size for a JTextField is 0, so that is what you are seeing.

You have a couple of different problems:

p_addIng.setPreferredSize(ingPanelDim);

You are artificially restricting the size of the panel, which is causing the text field to display at its minimum size. Remove that statement.

Also, you appear to be attempting to have the text field and combo box fill the same space as the button. If you want to do this then you need to have the button span two columns:

//gbc_ing.gridx = 2;
gbc_ing.gridx = 1;
gbc_ing.gridwidth = 2;

Having said the above you seem to miss the point of using a layout manager. You should NOT be attempting to set the preferred size of each component. You define the component and let the layout manager do the work.

For example, when creating a JTextField you should be using:

JTextField textField = new JTextField(10);

to give a suggestion of how big the text field should be.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM