GridBagLayout覆盖上一行

时间:2013-11-10 09:47:43

标签: java swing user-interface awt

我有这段代码为每个问题添加一系列问题和4个答案。但是当我添加第3个问题时,它会覆盖前一行。可以帮助我解决这个问题。我只需要提示一下为什么它正在这样做

package Generators;

/**
 *
 * @author samim
 */
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
public class CreateFormFields
{
    // Field members

    static JPanel panel = new JPanel();
    static Integer indexer = 1;
    // static List<JLabel> question = new ArrayList<JLabel>();
    static List<JTextField> question = new ArrayList<JTextField>();
    static List<JTextField> ans1 = new ArrayList<JTextField>();
    static List<JTextField> ans2 = new ArrayList<JTextField>();
    static List<JTextField> ans3 = new ArrayList<JTextField>();
    static List<JTextField> ans4 = new ArrayList<JTextField>();
    static List<JTextField> result = new ArrayList<JTextField>();

    public static void main(String[] args)
    {
    // Construct frame
    JFrame frame = new JFrame();
    frame.setLayout(new GridBagLayout());
    frame.setPreferredSize(new Dimension(990, 990));
    frame.setTitle("Form Creator");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // Frame constraints
    GridBagConstraints frameConstraints = new GridBagConstraints();

    // Construct button
    JButton addButton = new JButton("Add");

    addButton.addActionListener(new ButtonListener());

    // Add button to frame
    frameConstraints.gridx = 0;
    frameConstraints.gridy = 0;
    frame.add(addButton, frameConstraints);

    // Construct panel
    panel.setPreferredSize(new Dimension(950, 400));
    panel.setLayout(new GridBagLayout());

    JScrollPane scrollPane = new JScrollPane(panel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
        JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    scrollPane.setPreferredSize(new Dimension(900, 400));
    frameConstraints.gridx = 0;
    frameConstraints.gridy = 1;
    frame.add(scrollPane, frameConstraints);

    // Pack frame
    frame.pack();

    // Make frame visible
    frame.setVisible(true);
    }

    static class ButtonListener implements ActionListener
    {
    @Override
    public void actionPerformed(ActionEvent arg0)
    {
        // Clear panel
        panel.removeAll();
        panel.setPreferredSize(new Dimension(950,panel.getHeight()+200));
        // Create label and text field
        JTextField jTextField = new JTextField();
        JTextField jTextField2 = new JTextField();
        JTextField jTextField3 = new JTextField();
        JTextField jTextField4 = new JTextField();
        JTextField jTextField5 = new JTextField();
        JTextField jTextField6 = new JTextField();

        question.add(jTextField);
        ans1.add(jTextField2);
        ans2.add(jTextField3);
        ans3.add(jTextField4);
        ans4.add(jTextField5);
        result.add(jTextField6);

        // Create constraints
        GridBagConstraints textFieldConstraints = new GridBagConstraints();
        GridBagConstraints labelConstraints = new GridBagConstraints();
        GridBagConstraints gridans1 = new GridBagConstraints();
        GridBagConstraints temp = new GridBagConstraints();
        // Add labels and text fields
        for(int i = 1; i <= indexer; i++)
        {
        int R = (int) (Math.random() * 255);
        int G = (int) (Math.random() * 255);
        int B = (int) (Math.random() * 255);
        String total = "rgb(" + R + "," + G + "," + B + ")";
        // Label constraints
        labelConstraints.gridx = 0;
        labelConstraints.gridy = i * 7;
        labelConstraints.insets = new Insets(5, 300, 5, 300);
        panel.add(new JLabel("<html><font color='" + total + "'>Question&nbsp;" + i + "<font></html>"),
            labelConstraints);


        temp.gridx = 0;
        temp.gridy = i * 8;
        temp.insets = new Insets(10, -550, 10, 2);
        panel.add(new JLabel("Question :"), temp);
        // Text field constraints
        textFieldConstraints.fill = 1;//GridBagConstraints.HORIZONTAL;
        textFieldConstraints.insets = new Insets(10, -550, 10, 0);
        textFieldConstraints.gridy = i * 8;
        panel.add(question.get(i - 1), textFieldConstraints);

        gridans1.fill = 1;//GridBagConstraints.HORIZONTAL;
        gridans1.insets = new Insets(10, -550, 10, 290);
        gridans1.gridy = i * 9;
        temp.gridy = i * 9;
        panel.add(new JLabel("Answer 1 :"), temp);
        panel.add(ans1.get(i - 1), gridans1);

        gridans1.gridy = i * 10;
        temp.gridy = i * 10;
        panel.add(new JLabel("Answer 2 :"), temp);
        panel.add(ans2.get(i - 1), gridans1);

        gridans1.gridy = i * 11;
        temp.gridy = i * 11;
        panel.add(new JLabel("Answer 3:"), temp);
        panel.add(ans3.get(i - 1), gridans1);

        gridans1.gridy = i * 12;
        temp.gridy = i * 12;
        panel.add(new JLabel("Answer 4:"), temp);
        panel.add(ans4.get(i - 1), gridans1);

        gridans1.gridy = i * 13;
        temp.gridy = i * 13;
        panel.add(new JLabel("Good Result :"), temp);
        panel.add(result.get(i - 1), gridans1);

        }
        // Align components top-to-bottom

        // Increment indexer
        indexer++;
        panel.updateUI();
    }
    }
}

1 个答案:

答案 0 :(得分:0)

四个GridBagConstrains,许多循环组件:性能差,代码读取样式太复杂。最好更改代码设计:

  1. 在处理相似类型组件的组时,请尝试将它们包含在另一个Container Component中:

    MyQuestionPanel extends JPanel
    {
        public JLabel questionLab;
        public JTextField qAnsField1;
        public JTextFeild qAnsField2;
    
     MyQuestionPanel(int questionNo)
     {
       setLayout(/* GridBagLayout any layout relevant to your design */);
       //add your compoenents suing add(component, gridBagConstraint),  
       //or with relevant add() method e.g., questionLab, qAnsField1, qAnsField2
     }
    
    } 
    
  2. 现在,假设您有根面板,它将维护问题面板(容器是问题标签和答案输入字段),具有必要的布局(BoxLayout或其他与您的设计相关的布局),创建MyQuestionPanel的新实例并将其添加到root面板。您不需要删除所有问题面板并将其重新添加到Button Click上的root面板,就像您正在做的那样,而只需简单地添加root.add(MyQuestionPanel)

  3. 您无需致电updateUI();实际上你不应该在这种情况下,因为它将首先卸载你对调用组件的所有属性,然后通过额外的调用revalidate()repaint()重新安装UI。只需致电root.revalidate()然后再root.repaint(),即可反映添加和删除组件的更改。

  4. 如果你这样做,你会看到你的代码更短,更简单,更好。试一试。