简体   繁体   English

Java JPanel通过JTextArea不断发展

[英]Java JPanel keeps growing with JTextArea

I was testing something with JPanel. 我正在使用JPanel进行测试。 When I added random text to the JTextArea inside it, it kept increasing the size of the JPanel until it reached the edge. 当我向其中的JTextArea添加随机文本时,它会不断增加JPanel的大小,直到到达边缘为止。

How do I keep the text inside the JPanel without stretching it? 如何在不拉伸的情况下将文本保留在JPanel中?

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. 编辑:添加了其余的代码,并将textarea添加到了滚动窗格,并将滚动窗格添加到了Jpanel,现在文本没有显示在面板中。

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("");
}





}

You will want to get your JTextArea into JScrollPane , as Adeel said in the comments (+1), then control it with GridBagLayout . 如Adeel在评论(+1)中所述,您将希望将JTextArea放入JScrollPane中,然后使用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 . 无需设置组件边界,首选大小等。如果要使用GridBagLayout ,则必须学习weights如何与fillanchor 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). 在下面的代码中,将gbc.fill HORIZONTAL更改为VERTICAL并交换我用于向window添加scroll weights (因此应为weightx = 0, y = 1),或将fill更改为BOTH并使两个权重均等于1(在这种情况下) ,您可以注释掉我最后添加的这个空JLabel )。 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. mainTextArea加入而gbc.fillHORIZONTAL ,没有权重并且没有内部JScrollPane -这就是为什么它延伸。 And be careful with ipads. 并注意使用iPad。

SSCCE (comments in code) SSCCE(代码中的注释)

 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 如何使用GridBagLayout

You can also add scroll directly to window . 您也可以将scroll直接添加到window panel was created just for illustration purposes. panel仅用于说明目的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM