0

I have this simple code:

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SpringLayout;
import javax.swing.border.LineBorder;

@SuppressWarnings("serial")
public class MyFrame extends JFrame{

    SpringLayout layout;
    JPanel contentPane;
    JPanel pane1;

    public MyFrame(){

        layout=new SpringLayout();
        contentPane=new JPanel(layout);
        setContentPane(contentPane);
        setSize(new Dimension(800,600));

        pane1=new JPanel(new SpringLayout());
        pane1.setPreferredSize(new Dimension(200,200));
        pane1.setBorder(new LineBorder(Color.black));

        layout.putConstraint(SpringLayout.WEST, pane1, 0, SpringLayout.WEST, contentPane);
        layout.putConstraint(SpringLayout.EAST, pane1, getWidth()/2, SpringLayout.WEST, contentPane);
        contentPane.add(pane1);

        setEvents();
        setVisible(true);
    }

    private void setEvents(){

        addWindowListener(new WindowAdapter(){

            public void windowClosing(WindowEvent e){

                dispose();
                System.exit(0);
            }
        });

        this.addComponentListener(new ComponentListener(){

            @Override
            public void componentHidden(ComponentEvent arg0) {}

            @Override
            public void componentMoved(ComponentEvent arg0) {}

            @Override
            public void componentResized(ComponentEvent arg0) {

                System.out.println("RESIZING EVENT:");
                System.out.println("Frame Size: "+getWidth()+", "+getHeight());
                System.out.println("Pane1 Size: "+pane1.getWidth()+", "+pane1.getHeight()+"\n");


                layout.putConstraint(SpringLayout.EAST, pane1, getWidth()/2, SpringLayout.WEST, contentPane);
                contentPane.revalidate();
                contentPane.repaint();
            }

            @Override
            public void componentShown(ComponentEvent arg0) {}
        });
    }

    public static void main(String[] args){

        MyFrame frame=new MyFrame();
    }
}

I'm having trouble in getting the actual size of my pane1 component.

if I execute my code, MAXIMIZE and restore my window, numbers are wrong. Let me explain with a simple output of this code:

RESIZING EVENT: Frame Size: 800, 600 Pane1 Size: 400, 200

RESIZING EVENT: Frame Size: 800, 600 Pane1 Size: 400, 200

RESIZING EVENT: Frame Size: 1382, 744 Pane1 Size: 400, 200 maximizing here

RESIZING EVENT: Frame Size: 800, 600 Pane1 Size: 691, 200 restoring here

As you can see, the last dimension value (691, 200) should be referred to (1382,744) frame dimension, and not to the last one (800,600)...

calling revalidate and repaint methods updates my graphics (showing what is expected from this code) but doesn't help with this problem. Any help is appreciated

Francesco Rizzi
  • 631
  • 6
  • 24
  • Why not use a single row, two column `GridLayout` for that section of the GUI? If you put a panel with the grid layout in the `PAGE_START` of a `BorderLayout`, it will appear at the top of the border layout, stretched to the full width & divided horizontally into halves. – Andrew Thompson Jul 07 '17 at 15:52
  • I will check it out, but i would like to manage things with this layout, because i like it and i'm trying to learn it – Francesco Rizzi Jul 07 '17 at 22:35
  • Can you clarify what you're trying to do? i.e. What is the expected output? – Amber Jul 10 '17 at 20:07
  • I want to automatically resize pane1 to be the exact half of my contentpane. I want to achieve this using this kind of configuration, but as you can see in the output messages, the code gives me wrong size values... – Francesco Rizzi Jul 10 '17 at 20:48

1 Answers1

0

The problem is that contentPane is being used in two different conflicting roles. First the code uses contentPane as the content pane of MyFrame with a call to setContentPane(contentPane). Next, contentPane is treated as a child of itself when used as an argument to layout.putConstraint.

The content pane of a JFrame is the parent of a children of that JFrame and the container for which the layout is applied. See [RootPaneContainer][1].

Therefore, you need a third panel. I suggest calling it panelWest and use it in the layout.putConstraint instead of contentPane. Don't forget to initialize it and add it to MyFrame, just like panel. And remove all calls to add contentPane to itself (which include adding it to MyFrame, which would be adding it to itself), and remove all setting of layout constaints for contentPane as if it is a child of MyFrame.

Jason
  • 11,709
  • 9
  • 66
  • 82