JPanel 在另一个 JPanel 中调整大小

JPanel sizing inside Another JPanel

我真的需要帮助。我一直在调整添加到主面板的 gameBoardPanel JPanel 的大小时遇到​​问题。我尝试过的一切,包括调整它的大小都没有帮助,我基本上想将 400x400 的 gameBoardPanel 添加到主面板(这是 400x500),留下 400x100 space 用于其他按钮 e.x return 到菜单等。任何帮助将不胜感激!

谢谢!

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

public class SliderPractice extends JFrame implements ActionListener {

    private int numberOfRows, mode;
    private JPanel gameBoardPanel, menuPanel, main; //create a panel to add to JFRAME
    private int emptyIndex; //Variable will track the empty spot
    private int moves = 0;
    JButton[] buttons, compareButtons;
    private JLabel radioButtons, radioButtons1;
    private ButtonGroup radioButtonGroup1, radioButtonGroup2;
    private JButton start, displayInstructions = new JButton(); //buttons on start panel
    private JTextArea title;
    private JRadioButton easy, medium, hard, extreme, three, four, five, six; //Radio buttons allow user to only select 1 of 3

    public SliderPractice()
    {
        super("Slider! - By: Michel V.");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400,400);  //Overall size of grid but window
                           //is resizable by default. Layout
                           //Manager takes care of the necessary scaling.

        setResizable(false); //set resizable false for menu
        menu(); //calling menu
    }

    public void actionPerformed(ActionEvent e) { //when an action is performed

        if (e.getSource().equals(start)){ //Start button
            startUp(); //starts up game
        }

        for(int i = 0 ; i < buttons.length; i++) //checks for all the game buttons if any were pressed
        {
            if(e.getSource() == buttons[i]) //if a specific game button is pressed
            {
                if(isNextTo(i, emptyIndex)==true) //calling isNextTo to make sure its beside one another
                {
                    swapPieces(i); //if its beside, swap pieces and increase number of moves
                    moves++;
                }
            }
        }

        if(win()){ //if Win == true

            int select = JOptionPane.showConfirmDialog(this, "You won with " + moves + " moves! Play same settings again(Y/N)?\n                     Or press cancel to exit!");
            //Yes clicked - Play again
            if (select == JOptionPane.YES_OPTION){
                scramble();
                moves = 0;
            }//no picked, resetGUI!
            else if (select == JOptionPane.NO_OPTION){
                resetGUI();
            }//if Cancel or closed is picked, exit program
            else if (select == JOptionPane.CANCEL_OPTION){
                System.exit(0);
            }
            else if (select == JOptionPane.CLOSED_OPTION){
                System.exit(0);
            }
        }
    }

    public void gamePanel(int numberRows){

        numberOfRows = numberRows;
        buttons = new JButton[numberOfRows*numberOfRows];  //Make room for as many buttons as needed for picked number of Rows
        compareButtons = new JButton[numberOfRows*numberOfRows];

        Font f = new Font("Arial", Font.BOLD, 22);
        Color[] colours = {Color.red, Color.green};

        gameBoardPanel = new JPanel();
        gameBoardPanel.setLayout(new GridLayout(numberOfRows,numberOfRows,5,5)); // 4x4 grid with 5 pixel 
                                                           // vert/horz dividers
        gameBoardPanel.setBackground(Color.white); //Allows empty space to be black

        for (int i = 0; i < buttons.length; i++)  //From i is 0 to 15
        {
            int colourIndex = 0;  //Start with Orange

            compareButtons[i] = new JButton("" + i);
            buttons[i] = new JButton("" + i);  //Constructor sets text on new buttons
            buttons[i].setSize(100,100);  //Button size, but don't really need this line
                                          //line since we are using Layout Manager
            if (numberOfRows %2 ==0){
                if (i % 2 == 0)        //Alternate orange and white for evens and odds
                    colourIndex = 1;
                if ((i/4)%2 == 0)
                    colourIndex = 1-colourIndex;
            }
            else{
                if(i % 2 == 0)
                    colourIndex = 1;
            }

            buttons[i].setBackground(colours[colourIndex]);
            buttons[i].setForeground(Color.white);   //Text colour
            buttons[i].setFont(f);
            buttons[i].addActionListener(this);   //Set up ActionListener on each button
            gameBoardPanel.add(buttons[i]);    //Add buttons to the grid layout of 
                                               //gameBoardPanel
        }

        emptyIndex=(numberOfRows*numberOfRows-1);
        buttons[emptyIndex].setVisible(false);
    }

    public void menu(){

        Font f = new Font("Arial", Font.BOLD, 26);
        Font t = new Font("Trebuchet MS", Font.BOLD, 13);
        Color[] colours = {Color.red, Color.green};
        /*--- JPanel for Start Menu ---*/
        menuPanel = new JPanel();
        menuPanel.setLayout(null);
        menuPanel.setBackground(colours[0]);
        menuPanel.setVisible(true);
        //Title
        title = new JTextArea("Michel's Slider \n       Game!");
        title.setLineWrap(true);
        title.setWrapStyleWord(true);
        title.setBounds(100, 10, 250, 60);
        title.setFont(f);
        title.setBorder(BorderFactory.createEmptyBorder());
        title.setBackground(colours[0]);
        title.setEditable(false);
        title.setEnabled(false);
        title.setDisabledTextColor(Color.BLACK);
        //Label for radio buttons
        radioButtons = new JLabel("Choose the difficulty for this game:");
        radioButtons.setFont(new Font("Trebuchet MS", Font.BOLD, 17));
        radioButtons.setBounds(50, 155, 400, 20);
        //Radio buttons to select picture to play with
        easy = new JRadioButton("Easy");
        easy.setBackground(colours[0]);
        easy.setBounds(15, 178, 100, 20);
        easy.setActionCommand("Mode 1");
        easy.setFont(t);
        easy.setSelected(true); //Default selection
        medium = new JRadioButton("Medium");
        medium.setBackground(colours[0]);
        medium.setBounds(120, 178, 100, 20);
        medium.setFont(t);
        hard = new JRadioButton("Hard");
        hard.setBackground(colours[0]);
        hard.setBounds(215, 178, 100, 20);
        hard.setFont(t);
        extreme = new JRadioButton("Extreme");
        extreme.setBackground(colours[0]);
        extreme.setBounds(310, 178, 100, 20);
        extreme.setFont(t);
        //Add radio buttons to a group
        radioButtonGroup1 = new ButtonGroup();
        radioButtonGroup1.add(easy);
        radioButtonGroup1.add(medium);
        radioButtonGroup1.add(hard);
        radioButtonGroup1.add(extreme);

        radioButtons1 = new JLabel("Choose the size for this game:");
        radioButtons1.setFont(new Font("Trebuchet MS", Font.BOLD, 17));
        radioButtons1.setBounds(68, 100, 400, 20);
        //Radio buttons to select picture to play with
        three = new JRadioButton("3x3");
        three.setBackground(colours[0]);
        three.setBounds(15, 124, 110, 20);
        three.setActionCommand("Mode 1");
        three.setFont(t);
        three.setSelected(true); //Default selection
        four = new JRadioButton("4x4");
        four.setBackground(colours[0]);
        four.setBounds(120, 124, 100, 20);
        four.setFont(t);
        five = new JRadioButton("5x5");
        five.setBackground(colours[0]);
        five.setBounds(215, 124, 100, 20);
        five.setFont(t);
        six = new JRadioButton("6x6");
        six.setBackground(colours[0]);
        six.setBounds(310, 124, 100, 20);
        six.setFont(t);
        //Add radio buttons to a group
        radioButtonGroup2 = new ButtonGroup();
        radioButtonGroup2.add(three);
        radioButtonGroup2.add(four);
        radioButtonGroup2.add(five);
        radioButtonGroup2.add(six);


        //Start game button
        start = new JButton("Start Game");
        start.addActionListener(this);
        start.setBounds(110, 290, 170, 35);
        start.setBackground(colours[1]);
        start.setFont(new Font("Trebuchet MS", Font.BOLD, 22));
        //Instructions button
        displayInstructions = new JButton("Instructions");
        displayInstructions.addActionListener(this);
        displayInstructions.setBounds(130, 335, 130, 20);
        displayInstructions.setBackground(colours[1]);
        displayInstructions.setFont(new Font("Trebuchet MS", Font.BOLD, 17));

        //Add components to start panel
        menuPanel.add(start);
        menuPanel.add(displayInstructions);
        menuPanel.add(title);
        menuPanel.add(easy);
        menuPanel.add(medium);
        menuPanel.add(hard);
        menuPanel.add(extreme);
        menuPanel.add(radioButtons);
        menuPanel.add(three);
        menuPanel.add(four);
        menuPanel.add(five);
        menuPanel.add(six);
        menuPanel.add(radioButtons1);
        /*--- End Start Menu JPanel ---*/   
        add(menuPanel);
        setVisible(true);
    }

    public static void main(String[] args) {

        new SliderPractice();               //Run constructor for class
    }


    private void swapPieces(int btnIndex)   //Send along button that was pushed
    {
        buttons[emptyIndex].setText(buttons[btnIndex].getText());  //Move over text
                                                                   //to blank button
        buttons[btnIndex].setVisible(false); //Turn off visibility of button that was pushed
                                             //and background will show through as black
        buttons[emptyIndex].setVisible(true);//Turn on visibility of the old blank button
        emptyIndex = btnIndex;               //Update the emptyIndex to the button that was
                                             //pushed.
    }

    private boolean isNextTo(int choice, int blankButton)
    {
        if(choice/numberOfRows==blankButton/numberOfRows){
            if(Math.abs(choice-blankButton)==1) return true;
        }
        else if(Math.abs(choice/numberOfRows-blankButton/numberOfRows)==1) {
            if(Math.abs(choice-blankButton)==numberOfRows) { 
                return true;
            }
        }
        return false;
    }

    private boolean win()
    {
        int count = 0;

        for (int i = 0; i < buttons.length; i++)  //From i is 0 to 15
        {
            if(buttons[i].getText().equals(compareButtons[i].getText()))
            {
                count++;
            }
            else{
                break;
            }
        }

        if (count == (numberOfRows*numberOfRows-1))
            return true;
        else
            return false;
    }

    private void scramble()
    {
        int s = 0;
        int g;
        int max = (int) Math.pow(numberOfRows, mode);

        while (s<max)
        {
            g = (int) ((Math.random()*(numberOfRows*numberOfRows))-1);

            if(isNextTo(g, emptyIndex)==true)
            {
                swapPieces(g);
                s++;
            }
        }
    }

    private void startUp(){

        int size = 0;

        //Set image on button according to radio button selection
        if (three.isSelected()){
            size = 3;
        }

        else if (four.isSelected()){
            size = 4;
        }

        else if (five.isSelected()){
            size = 5;
        }

        else if (six.isSelected()){
            size = 6;
        }

        if (easy.isSelected()){
            mode = 2;
        }

        else if (medium.isSelected()){
            mode = 3;
        }

        else if (hard.isSelected()){
            mode = 4;
        }

        else if (extreme.isSelected()){
            mode = 5;
        }

        gamePanel(size);

        setSize(400, 500);
        gameBoardPanel.setEnabled(false);
        //Switch panels from start panel to main panel
        main = new JPanel();
        menuPanel.setVisible(false);
        remove(menuPanel);
        main.add(gameBoardPanel);
        main.setSize(400, 400);
        main.setBackground(Color.white);
        add(main);
        setResizable(true);
        //Shuffle Pieces
        scramble();
    }

    private void resetGUI(){
        numberOfRows = 0;
        moves = 0;
        emptyIndex = 0;
        setResizable(false);
        setSize(400,400);
        remove(gameBoardPanel);
        add(menuPanel);
        menu();
        mode = 0;
    }
}

真的很难理解你想要达到的目标。你想为底部的哪些按钮腾出空间??屏幕应该是什么样子?

无论如何,我认为您应该使用不同的面板和布局管理器来解决您的问题,而我认为最能帮助您的是 BorderLayout。

如果您希望您的 gameBoardPanel 在游戏开始时完全适合 window,您可以在 startUp() 方法的末尾将代码更改为如下内容:

    //Switch panels from start panel to main panel
    main = new JPanel(new BorderLayout());
    menuPanel.setVisible(false);
    remove(menuPanel);
    main.add(gameBoardPanel, BorderLayout.CENTER);

    JPanel buttonsPanel = new JPanel();
    buttonsPanel.setPreferredSize(new Dimension(400, 100));
    main.add(buttonsPanel, BorderLayout.SOUTH);

从您的代码来看,很明显您还没有阅读布局管理器教程。根据您的描述,您几乎肯定想要使用 BorderLayout,将您的游戏面板放在 CENTER 中,将您的按钮面板放在 SOUTH 中。

CENTER 位置的组件全部留在 space 上,SOUTH 位置的组件获得其首选高度,但占用所有可用宽度。

https://docs.oracle.com/javase/tutorial/uiswing/layout/border.html