Java中Layouts中的元素都处于相同的位置

时间:2012-04-07 15:23:54

标签: java swing layout grid-layout

我在Java Swing中进行编码,出于某种原因,当我向gridlayout添加两个元素时,它们都采用相同的位置。我已经尝试将其简化为不会失败的东西,然后从那里开始构建,但唉,它仍然没有用。

程序中行为不当的代码是:

        bodyPanelMain.setLayout(new GridLayout(4, 1, 10, 10));
        JTextArea one = new JTextArea("Hi");
        one.setLineWrap(true);
        one.setSize(100, 100);
        JTextArea two = new JTextArea("Goodbye");
        two.setLineWrap(true);
        two.setSize(100, 100);
        bodyPanelMain.add(one);
        bodyPanelMain.add(two);
        bodyPanelMain.repaint();

如果我将JTextArea的宽度设置为200并且背景设置为不同的颜色,则很明显它背后可见,所以它肯定会添加所有正确的元素,它们的位置是错误的。

编辑:这是我想要做的非常简短的版本。

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class minimessageboard extends Applet implements ActionListener {

JPanel mainPanel;
JPanel buttonPanel;
JButton announcements, websites;
JPanel bodyPanel, bodyPanelMain;

public minimessageboard() {
    this.setSize(600, 400);

    mainPanel = new JPanel(new BorderLayout());
    mainPanel.setPreferredSize(new Dimension(this.getWidth(), this.getHeight()));
    this.add(mainPanel);

    buttonPanel = new JPanel(new GridLayout(6, 1, 10, 10));
    mainPanel.add(buttonPanel, BorderLayout.WEST);

    announcements = new JButton("Announcements");
    this.formatButton(announcements);
    announcements.setActionCommand("announcements");
    buttonPanel.add(announcements);

    websites = new JButton("Websites");
    this.formatButton(websites);
    websites.setActionCommand("websites");
    buttonPanel.add(websites);

    bodyPanel = new JPanel(new BorderLayout());
    bodyPanel.setSize(200, 500);
    bodyPanel.setPreferredSize(new Dimension(200, 500));
    mainPanel.add(bodyPanel, BorderLayout.CENTER);

    bodyPanelMain = new JPanel(new BorderLayout());
    bodyPanel.add(bodyPanelMain, BorderLayout.CENTER);
    bodyPanelMain.setLayout(new GridLayout(4, 1, 10, 10));
    JButton one = new JButton("Roar");
    bodyPanelMain.add(one);
    bodyPanelMain.revalidate();
    bodyPanelMain.repaint();
}

public static void main(String args[]) {
    JFrame overall = new JFrame(); 
    overall.pack();
    overall.setVisible(true);
    overall.add(new minimessageboard());
}

public void formatButton(JButton b){
    b.setPreferredSize(new Dimension(150, 33));
    b.addActionListener(this);
}

public void actionPerformed(ActionEvent arg0) {
    String action = arg0.getActionCommand();
    bodyPanelMain.removeAll();
    if (action.equals("websites")){
        System.out.println("Fires!");
        bodyPanelMain.setLayout(new GridLayout(4, 1, 10, 10));
        JButton one = new JButton("Hi");
        JButton two = new JButton("Goodbye");
        bodyPanelMain.add(one);
        bodyPanelMain.add(two);
        bodyPanelMain.revalidate();
    }
    bodyPanelMain.repaint();
}
}

基本上,当您点击网站时,“Hi”和“Bye”应该会显示出来。如果我将网站if中的代码移动if语句(if(action.equals(“website”))直到原始构造函数,它看起来很好。代码输出“Fires!”,所以我100%肯定它会到达那个部分。注意,我将它从JTextArea更改为JButton因为我将使用JButtons而不是JTextArea。

1 个答案:

答案 0 :(得分:3)

不要设置JTextArea的大小,因为当文本超出文本区域大小并且发现它不会滚动时,它将无法正常工作。而是设置首选的行和列值,然后让JTextArea大小本身。关于你的问题:你是否在GUI渲染后添加了这些组件?如果是这样,在收到JTextAreas之后,你在bodyPanelMain上调用revalidate()吗?如果这没有帮助,请考虑创建和发布sscce。

例如,这对我来说很好用:

import java.awt.GridLayout;
import javax.swing.*;

public class SwingFoo {
   private static final int ROWS = 10;
   private static final int COLS = 16;

   private static void createAndShowGui() {
      JPanel bodyPanelMain = new JPanel();
      bodyPanelMain.setLayout(new GridLayout(4, 1, 10, 10));
      JTextArea one = new JTextArea("Hi", ROWS, COLS);
      one.setLineWrap(true);
      // one.setSize(100, 100);
      JTextArea two = new JTextArea("Goodbye", ROWS, COLS);
      two.setLineWrap(true);
      // two.setSize(100, 100);
      bodyPanelMain.add(new JScrollPane(one));
      bodyPanelMain.add(new JScrollPane(two));
      // bodyPanelMain.repaint();

      JFrame frame = new JFrame("SwingFoo");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(bodyPanelMain);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}