How elements in Container adjust when we resize wi

2019-06-24 19:37发布

问题:

Below is the code for a Window which changes color when the user clicks a button, and changes the text of a label when he clicks the other button.

It has two buttons, a panel for holding buttons, a label, and a panel for graphics.

Conceptual explanation: First, I added the label to the North part of the frame using the default BorderLayout. Then I added the two buttons in a separate panel, and I added that panel to the South part of the main frame. Then I added the panel for the graphics in the Center of the main frame.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
class GuiAnimation extends JFrame
{

JButton colorBut;
JButton labelBut;
JLabel label;
PaintCanvas firstCanvas;
JPanel buttonPanel;

GuiAnimation()
{

    colorBut = new JButton("Color Change");
    labelBut = new JButton("Text Change");
    label = new JLabel("I will change");
    firstCanvas = new PaintCanvas();
    buttonPanel = new JPanel();
    addListener(); //May be i should make different method for different component for the flexibility.But here program is small.
    addEverything();
}

private void addListener()
{

    colorBut.addActionListener(new ColorListener());
    labelBut.addActionListener(new LabelListener());
}

private void setButtonInPanel()
{
    int pad = 80;
    buttonPanel.setLayout(new FlowLayout(FlowLayout.LEADING, pad, 20));
    buttonPanel.add(colorBut);
    buttonPanel.add(labelBut);
}
void addEverything()    //Here things are done with Layouts.
{
    //add the label to the top of the window.
    this.getContentPane().add(BorderLayout.NORTH, label);
    //add button inside the panel.  
    setButtonInPanel();
    //add that panel that has button to the frame.
    this.getContentPane().add(BorderLayout.SOUTH, buttonPanel);
    //add the graphics canvas to the frame.
    this.getContentPane().add(BorderLayout.CENTER, firstCanvas);
}

class PaintCanvas extends JPanel
{

    public void paintComponent(Graphics g)
    {
        int red = (int) (Math.random() * 255);
        int green = (int) (Math.random() * 255);
        int blue = (int) (Math.random() * 255);

        Color randomColor = new Color(red, green, blue);

        g.setColor(randomColor);
        g.fillRect(0, 0, getWidth(), getHeight());
    }

}

class ColorListener implements ActionListener
{

    public void actionPerformed(ActionEvent e){

        firstCanvas.repaint();
    }
}

class LabelListener implements ActionListener
{

    public void actionPerformed(ActionEvent e){

        if ( label.getText().equals("I will change"))
            label.setText("yes yes yes clicked");
        else 
            label.setText("I will change");
    }
}

 public static void main(String[] args) {

    GuiAnimation gui = new GuiAnimation();
    gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    gui.setSize(500,600);
    gui.setVisible(true);
 }
}

Here is the output of above code.So far so good.

But when I start to slide from the right-hand side, the following happens:

Now the right wall of the window is coming towards the left, but the buttons are stationary. Continuing this we get:

However, if we resize from the left side, we get:

Here the button seems to move towards the right, along with the frame (maintaining its distance from the frame boundary). This is the opposite of the previous case. But Why? How?

Finally, we have:

Continuing this, the "ColorChange" button also becomes partially invisible.

Why are these two different things happening, if we slide from right to left versus left to right?

I have searched, but I was unable to find an accurate answer to this, so finally I am asking here: Why and How?

回答1:

You have explained the problem, but you haven't explained the requirement.

Maybe you should consider a Box Layout

panel.add( Box.createHorizontalGlue() );
panel.add( button1 );
panel.add( Box.createHorizontalStrut(20) );
panel.add( button2 );
panel.add( Box.createHorizontalGlue() );

This will create a panel where the buttons remain centered with a gap of 20 pixels between the two buttons.



回答2:

It's because of your gap-value at

int pad = 80;
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEADING, pad, 20));

. It's always 80px. So the first button is always 80px away from the "beginning" of the panel. If you slide from right to left, nothing changes, except one button dissapears because there's not enough space to fill 3 gaps. However, if you slide from left to right, The first button doesn't vanish firstly because as mentioned before, it has to have a gap of 80px from the beginning. Sorry for my miserable english, but I hope I have helped.



回答3:

This could possibly what you need: https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/size.html

I haven't worked on Swing/JavaFX in a while, but I do believe that you can give frame.pack(); a shot.