0

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 Before

and this is how layout looks after uploading an image

After

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.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Daniel
  • 17
  • 4
  • 1) For better help sooner, [edit] to add a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) One way to get image(s) for an example is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). E.G. [This answer](https://stackoverflow.com/a/10862262/418556) hot links to an image embedded in [this question](https://stackoverflow.com/q/10861852/418556). – Andrew Thompson Jan 23 '19 at 18:03

1 Answers1

1
    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.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Thank you for solution but if possible i want to maintain the layout manager used but i have fixed it witch regards to your first point, I've edited the post to show how i've changed the grid width and height to appropriate numbers – Daniel Jan 23 '19 at 17:01
  • 1
    That's like saying "I really want to eat my soup with a fork, but you're telling me to use a spoon. How can I use a fork?" Sometimes you need to use the right tool for the right job. Grid Bag Layout is intended for dynamic layouts, not fixed ones. This use case is like the poster child for BorderLayout. – Roddy of the Frozen Peas Jan 23 '19 at 17:08