user8091792
user8091792

Reputation:

Java JPanel keeps growing with JTextArea

I was testing something with JPanel. When I added random text to the JTextArea inside it, it kept increasing the size of the JPanel until it reached the edge.

How do I keep the text inside the JPanel without stretching it?

public class Game
{
TitleScreenHandler tsHandler = new TitleScreenHandler();
ChoiceHandler choiceHandler = new ChoiceHandler();
ComponentHandler compHandler = new ComponentHandler();      

GridBagConstraints gbc = new GridBagConstraints();
Border whiteline = BorderFactory.createLineBorder(Color.WHITE);

JFrame window; 
Container con;
JPanel titlePanel , startPanel, mainTextPanel, choiceButtonPanel, playerPanel;
JLabel titleLabel, hpLabel, hpLabelNumber, weaponLabel, weaponLabelName;

public static JButton startButton, choice1,choice2,choice3,choice4,choice5,choice6,choice7,choice8;

public static JTextArea mainTextArea;

Font titleFont = new Font("Times New Roman", Font.PLAIN, 100);
Font normalFont = new Font("Times New Roman", Font.PLAIN, 30);

public static String playerName;
public static String weapon,position;

public static int playerHP;
public static int weaponDamage;

public static void main(String[] args)
{
    new Game();

}

public Game()
{
    window = new JFrame();
    window.setSize(1440,900);
    window.setTitle("W: " + window.getWidth() + " H: " + window.getHeight());
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.getContentPane().setBackground(Color.black);
    window.setLayout(new GridBagLayout());

    con = window.getContentPane();

    //Panels are used to make sections in the window (Background)
    //Labels are used to write in the sections/panels (Foreground)
    //Buttons can be pressed inside Panels

    //To make a text you need to design a panel, design its size/color,
    //Design its text the same way, then add it to the panel

    titlePanel = new JPanel();
    titlePanel.setBounds(100, 100,  1080 , 150);
    titlePanel.setBackground(Color.black);      

    titleLabel = new JLabel("Adventure");
    titleLabel.setForeground(Color.white);
    titleLabel.setFont(titleFont);

    startPanel = new JPanel();
    startPanel.setBounds(540, 600, 200, 100);
    startPanel.setBackground(Color.black);

    startButton = new JButton("START");
    startButton.setBackground(Color.black);
    startButton.setForeground(Color.white);
    startButton.setFont(normalFont);
    startButton.addActionListener(tsHandler);

    window.addComponentListener(compHandler);

    titlePanel.add(titleLabel);
    startPanel.add(startButton);

    con.add(titlePanel, gbc);

    gbc.gridx = 0;
    gbc.gridy = 2;

    con.add(startPanel, gbc);

    window.setVisible(true);
}

public void createGameScreen()
{
    titlePanel.setVisible(false);
    startButton.setVisible(false);

    mainTextPanel = new JPanel();
    //mainTextPanel.setBounds(100, 100, 1080, 250);
    mainTextPanel.setBackground(Color.black);
    mainTextPanel.setBorder(whiteline);

    mainTextArea = new JTextArea("This is the main text area");
    mainTextArea.setBounds(100,100,1080,250);
    mainTextArea.setBackground(Color.black);
    mainTextArea.setForeground(Color.white); 
    mainTextArea.setLayout(new GridLayout());
    mainTextArea.setFont(normalFont);
    mainTextArea.setLineWrap(true);
    mainTextArea.setWrapStyleWord(true);

    playerPanel = new JPanel();
    playerPanel.setBounds(100, 100, 1080, 50);
    playerPanel.setBackground(Color.blue);
    playerPanel.setLayout(new GridLayout(1,4));

    choiceButtonPanel = new JPanel();
    choiceButtonPanel.setBounds(500, 350, 300, 250);
    choiceButtonPanel.setLayout(new GridLayout(2,4, 50, 50));
    choiceButtonPanel.setBackground(Color.red);

    choice1 = new JButton("Choice 1");
    choice1.setBackground(Color.black);
    choice1.setForeground(Color.white);
    choice1.setFont(normalFont);
    choice1.setFocusPainted(false);
    choice1.addActionListener(choiceHandler);
    choice1.setActionCommand("c1");

    choiceButtonPanel.add(choice1);

    choice2 = new JButton("Choice 2");
    choice2.setBackground(Color.black);
    choice2.setForeground(Color.white);
    choice2.setFont(normalFont);
    choice2.setFocusPainted(false);
    choice2.addActionListener(choiceHandler);
    choice2.setActionCommand("c2");

    choiceButtonPanel.add(choice2);

    choice3 = new JButton("Choice 3");
    choice3.setBackground(Color.black);
    choice3.setForeground(Color.white);
    choice3.setFont(normalFont);
    choice3.setFocusPainted(false);
    choice3.addActionListener(choiceHandler);
    choice3.setActionCommand("c3");

    choiceButtonPanel.add(choice3);

    choice4 = new JButton("Choice 4");
    choice4.setBackground(Color.black);
    choice4.setForeground(Color.white);
    choice4.setFont(normalFont);
    choice4.setFocusPainted(false);
    choice4.addActionListener(choiceHandler);
    choice4.setActionCommand("c4");

    choiceButtonPanel.add(choice4);

    choice5 = new JButton("Choice 5");
    choice5.setBackground(Color.black);
    choice5.setForeground(Color.white);
    choice5.setFont(normalFont);
    choice5.setFocusPainted(false);
    choice5.addActionListener(choiceHandler);
    choice5.setActionCommand("c5");

    choiceButtonPanel.add(choice5);

    choice6 = new JButton("Choice 6");
    choice6.setBackground(Color.black);
    choice6.setForeground(Color.white);
    choice6.setFont(normalFont);
    choice6.setFocusPainted(false);
    choice6.addActionListener(choiceHandler);
    choice6.setActionCommand("c6");

    choiceButtonPanel.add(choice6);

    choice7 = new JButton("Choice 7");
    choice7.setBackground(Color.black);
    choice7.setForeground(Color.white);
    choice7.setFont(normalFont);
    choice7.setFocusPainted(false);
    choice7.addActionListener(choiceHandler);
    choice7.setActionCommand("c7");

    choiceButtonPanel.add(choice7);

    choice8 = new JButton("Choice 8");
    choice8.setBackground(Color.black);
    choice8.setForeground(Color.white);
    choice8.setFont(normalFont);
    choice8.setFocusPainted(false);
    choice8.addActionListener(choiceHandler);
    choice8.setActionCommand("c8");

    choiceButtonPanel.add(choice8);

    gbc.anchor = GridBagConstraints.PAGE_END;
    gbc.fill = GridBagConstraints.BOTH;

    gbc.gridx = 0;
    gbc.gridy = 0;

    con.add(playerPanel,gbc);

    gbc.fill = GridBagConstraints.HORIZONTAL;
    //gbc.ipadx = 750;
    gbc.ipady = 1000;
    gbc.gridwidth = 2;
    gbc.gridx = 1;
    gbc.gridy = 0;
    con.add(mainTextPanel,gbc);

    gbc.fill = GridBagConstraints.NONE;
    gbc.ipadx = 0;
    gbc.ipady = 0;
    gbc.gridx = 1;
    gbc.gridy = 5;
    con.add(choiceButtonPanel,gbc);

    hpLabel = new JLabel("HP: ");
    hpLabel.setFont(normalFont);
    hpLabel.setForeground(Color.white);

    hpLabelNumber = new JLabel();
    hpLabelNumber.setFont(normalFont);
    hpLabelNumber.setForeground(Color.white);

    weaponLabel = new JLabel("Weapon: ");
    weaponLabel.setFont(normalFont);
    weaponLabel.setForeground(Color.white);

    weaponLabelName = new JLabel();
    weaponLabelName.setFont(normalFont);
    weaponLabelName.setForeground(Color.white);

    playerPanel.add(hpLabel);
    playerPanel.add(hpLabelNumber);
    playerPanel.add(weaponLabel);
    playerPanel.add(weaponLabelName);
    mainTextPanel.add(mainTextArea, BorderLayout.PAGE_START);

    playerSetup();

}


public void playerSetup()
{
    playerHP = 15;
    weapon = "Fists";
    weaponLabelName.setText(weapon);
    hpLabelNumber.setText("" + playerHP);

    ForestEvents.townGate();
}

/*public void townGate()
{
    position = "towngate";

    mainTextArea.setText("You are at the gates of the town. A guard is standing in front of you. What do you do?");
    choice1.setText("Talk to the Guard");
    choice2.setText("Attack the Guard");
    choice3.setText("Leave");
    choice4.setText("");
}*/

public void talkGuard()
{
    position = "talkguard";

    mainTextArea.setText("Guard: Hello Stranger. I have never seen you before. I'm sorry but I cannot let you enter.");

    choice1.setText("Go Back");
    choice2.setText("");
    choice3.setText("");
    choice4.setText("");

}

public void attackGuard()
{
    position = "attackguard";

    mainTextArea.setText("Guard: HOW DARE YOU!\nThe guard fought back and hit you hard.\n(You received 3 damage)");
    playerHP -= 3;
    hpLabelNumber.setText("" + playerHP);

    choice1.setText("Go Back");
    choice2.setText("");
    choice3.setText("");
    choice4.setText("");

}

public void crossRoad()
{
    position = "crossroads";

    mainTextArea.setText("You are at the crossroad.\n Go south to go back to the town.");

    choice1.setText("Go North");
    choice2.setText("Go East");
    choice3.setText("Go South");
    choice4.setText("Go West");

}

public class ComponentHandler implements ComponentListener
{
    public void componentResized(ComponentEvent e)
    {
        Component c = (Component)e.getSource();
        window.setTitle("W: " + c.getWidth() + " H: " + c.getHeight());


    }

    @Override
    public void componentHidden(ComponentEvent e)
    {
        // TODO Auto-generated method stub

    }

    @Override
    public void componentMoved(ComponentEvent e)
    {

    }

    @Override
    public void componentShown(ComponentEvent e)
    {

    }
}

public class TitleScreenHandler implements ActionListener 
{
    public void actionPerformed(ActionEvent event)
    {
        createGameScreen();
    }
}

public class ChoiceHandler implements ActionListener
{
    public void actionPerformed(ActionEvent event)
    {
        String yourChoice = event.getActionCommand(); 

        switch (position) 
        {
            case "towngate":
                switch(yourChoice)
                {
                case "c1": 
                    talkGuard();
                    break;
                case "c2": 
                    attackGuard();
                    break;
                case "c3": 
                    crossRoad();
                    break;
                case "c4": 
                    break;
                }
                break;

            case "talkguard":
                switch(yourChoice)
                {
                case "c1":
                    ForestEvents.townGate();
                    break;
                }
                break;

            case "attackguard":
                switch(yourChoice)
                {
                case "c1":
                    ForestEvents.townGate();
                    break;  
                }
                break;

            case "crossroad":
                switch(yourChoice)
                {
                case"c1":
                    break;
                case"c2":
                    break;
                case"c3":
                    ForestEvents.townGate();
                    break;
                case"c4":
                    break;
                }
                break;


        }

    }

}

}

Edit: Added the rest of the code and added the textarea to the scrollpane and the scrollpane to the Jpanel now the text isnt showing up in the panel.

import javax.swing.JTextArea;

public class ForestEvents
{
String pos;
int hp;

public ForestEvents()
{
    pos = Game.position;
    hp = Game.playerHP;
}

public static void townGate()
{
    Game.position = "towngate";

    Game.mainTextArea.setText("You are at the gates of the town. A guard is standing in front of you. What do you do? \na\nas\n\n\n\n\\n"
            + "\n\n\n\1\n1\n\n\n\n\n\\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n1\n1\n2\n2\n3\n4\n6");
    Game.choice1.setText("Talk to the Guard");
    Game.choice2.setText("Attack the Guard");
    Game.choice3.setText("Leave");
    Game.choice4.setText("");
}





}

Upvotes: 0

Views: 329

Answers (1)

user6598750
user6598750

Reputation:

You will want to get your JTextArea into JScrollPane, as Adeel said in the comments (+1), then control it with GridBagLayout. No need to set component bounds, preferred size etc. If you want to use GridBagLayout, you have to learn how weights work with fill and anchor. In code below change gbc.fill HORIZONTAL to VERTICAL and swap weights I used for adding scroll to window (so it should be weightx=0,y=1), or change fill to BOTH and make both weights equal to 1 (in this case, you can comment out this empty JLabel I added at the end). Observe and learn.

In your code, you're not setting weights. So, as you may have guessed, everything has the same weight. mainTextArea is added while gbc.fill is HORIZONTAL, no weights and is not inside JScrollPane - that's why it stretches. And be careful with ipads.

SSCCE (comments in code)

 public class DontStretchMyTextArea {

    public static void main(String[] args) {
        JFrame window = new JFrame();
        window.setSize(1440, 900);
        window.setTitle("W: " + window.getWidth() + " H: " + window.getHeight());
        window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        window.setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.anchor = GridBagConstraints.NORTH;
        gbc.insets = new Insets(10, 10, 10, 10);

        JTextArea mainTextArea = new JTextArea( "This is the main text area" , 10 , 30 ); //here you can set how many rows/columns you want,
                                                                                          //but anyway GridBagLayout will recalculate size of component
                                                                                          //based on gbc.fill, weights and surrounding components
        //mainTextArea.setLayout(new GridLayout());
        mainTextArea.setLineWrap(true);
        mainTextArea.setWrapStyleWord(true);

        JScrollPane scroll = new JScrollPane(mainTextArea);
        scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

            JPanel panel = new JPanel();
            panel.setLayout(new GridBagLayout());
            GridBagConstraints panelGBC = new GridBagConstraints();

            panelGBC.weightx = 1;                    //I want to fill whole panel with JTextArea
            panelGBC.weighty = 1;                    //so both weights =1
            panelGBC.fill = GridBagConstraints.BOTH; //and fill is set to BOTH

            panel.add(scroll, panelGBC);
            panel.setBackground(Color.gray);//this shouldn't be visible


        gbc.weightx = 1;
        gbc.weighty = 0;
        window.add(panel, gbc);

        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.gridx++;
        window.add(new JLabel(), gbc); //GridBagLayout always needs component with both weights =1

        SwingUtilities.invokeLater(() -> { //we get our frame on EDT
            window.pack();
            window.setVisible(true);
        });
    }
}

How to use GridBagLayout

You can also add scroll directly to window. panel was created just for illustration purposes.

Upvotes: 1

Related Questions