2014-06-26 63 views
0

我正在構建一個簡單的應用程序,我可以用它來放置一些問題及其答案,並將它們保存到不同的數組列表中以備後用(類似於其中一個測驗卡一方面有問題,另一方面是答案),當我建立我的用戶界面時,我到達了一堵磚牆,我似乎無法通過。使組件跨越GridBagLayout中的多個單元格

下面的代碼

我想「下一個」按鈕,跨越多個列,比文本區域

enter image description here

但更寬當過我嘗試設置widthx變量多列沒有似乎會發生,有人可以解釋爲什麼會發生這種情況,並可能如何解決它? 謝謝

public class FillingCards extends JPanel implements ActionListener { 
    JTextArea question; 
    JTextArea answer; 
    JButton button; 
    ArrayList<String> questions; 
    ArrayList<String> answers; 
    GridBagConstraints gbc; 

    public static void main(String[] args) { 
     FillingCards card = new FillingCards(); 
     card.setupGUI(); 
     JFrame frame = new JFrame(); 
     frame.add(BorderLayout.CENTER, card); 
     frame.pack(); 
     frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
     frame.setBackground(Color.GRAY); 

    } 

    public FillingCards() { 
     gbc = new GridBagConstraints(); 
     question = new JTextArea(5, 5); 
     answer = new JTextArea(5, 5); 
     button = new JButton("next"); 

    } 

    public void setupGUI() { 

     this.setLayout(new GridBagLayout()); 
     gbc.fill = GridBagConstraints.BOTH; 
     JScrollPane qs = new JScrollPane(question); 
     qs.setPreferredSize(new Dimension(400, 400)); 
     qs.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 
     qs.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 
     gbc.gridx = 1; 
     gbc.gridy = 0; 
     this.add(qs, gbc); 
     gbc.gridx = 1; 
     gbc.gridy = 1; 
     this.add(new JLabel("Answer: "), gbc); 
     JScrollPane as = new JScrollPane(answer); 
     as.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 
     as.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 
     gbc.gridx = 1; 
     gbc.gridy = 2; 
     this.add(as, gbc); 
     gbc.gridx = 1; 
     gbc.gridy = 3; 
     gbc.fill = GridBagConstraints.HORIZONTAL; 
     this.add(button, gbc); 
     button.addActionListener(this); 
     questions = new ArrayList<>(); 
     answers = new ArrayList<>(); 
     question.setLineWrap(true); 
     answer.setLineWrap(true); 

    } 

    public void startFilling() { 
     questions.add(question.getText()); 
     answers.add(answer.getText()); 

     question.setText(null); 
     answer.setText(null); 

    } 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     startFilling(); 

    } 

} 
+0

GBC是基於列 – mKorbel

+0

對於[示例](http://stackoverflow.com/q/14755487/230513)。 – trashgod

回答

0

好的,你不小心遇到了一個怪癖。雖然佈局看起來很簡單,但 也讓我花了一些時間來解決這個問題。 (順便說一句,水平拉伸按鈕不是一個最佳的UI設計。)

原因是管理者的方式。如果佈局中不包含 連續的至少兩個組件,則無法跨組件。 您的佈局僅包含一列,因此,設置widthx> 1確實 不起作用。有兩種方法可以解決這個問題:我們可以在佈局中放置一些 虛擬元件,或者我們可以在 之前和之後放置一些空間來減小它們的寬度。

我提供了三種解決方案:a)具有虛擬標籤的GridBagLayout,b)具有插入的GridBagLayout 和c)帶有間隙的MigLayout。

Quiz cards

溶液1

package com.zetcode; 

import java.awt.BorderLayout; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextArea; 

public class FillingCards extends JPanel { 

    private JTextArea question; 
    private JTextArea answer; 
    private JButton button; 
    private JLabel label; 


    public FillingCards() { 


     setupGUI(); 
    } 

    private void setupGUI() { 

     question = new JTextArea(12, 22); 
     answer = new JTextArea(12, 22); 
     button = new JButton("Next"); 
     label = new JLabel("Answer"); 

     question.setBorder(
       BorderFactory.createEtchedBorder() 
     ); 

     answer.setBorder(
       BorderFactory.createEtchedBorder() 
     );   

     setLayout(new GridBagLayout()); 

     GridBagConstraints gbc = new GridBagConstraints(); 

     gbc.fill = GridBagConstraints.BOTH; 
     gbc.gridwidth = 1; 
     gbc.weightx = 1; 
     gbc.weighty = 1; 
     gbc.insets = new Insets(5, 10, 5, 10); 

     gbc.gridx = 1; 
     gbc.gridy = 0; 
     add(question, gbc); 

     gbc.anchor = GridBagConstraints.WEST; 
     gbc.fill = GridBagConstraints.NONE; 
     gbc.gridx = 1; 
     gbc.gridy = 1; 
     gbc.weighty = 0; 
     gbc.weightx = 0; 
     add(label, gbc); 

     gbc.fill = GridBagConstraints.BOTH; 
     gbc.gridx = 1; 
     gbc.gridy = 2; 
     gbc.weightx = 1; 
     gbc.weighty = 1; 
     add(answer, gbc); 

     gbc.gridwidth = 3; 
     gbc.weightx = 1; 
     gbc.weighty = 0; 
     gbc.gridx = 0; 
     gbc.gridy = 3; 
     gbc.fill = GridBagConstraints.HORIZONTAL; 
     add(button, gbc); 

     gbc.fill = GridBagConstraints.NONE; 
     gbc.gridwidth = 1; 
     gbc.weighty = 0; 
     gbc.weightx = 0; 
     gbc.gridx = 0; 
     gbc.gridy = 3; 
     add(new JLabel(" "), gbc); 

     gbc.gridx = 2; 
     gbc.gridy = 3; 
     add(new JLabel(" "), gbc); 

    } 

    public static void main(String[] args) { 

     JFrame frame = new JFrame("Quiz cards"); 
     FillingCards card = new FillingCards(); 
     frame.add(BorderLayout.CENTER, card); 
     frame.pack(); 
     frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    }  
} 

兩個標籤被放置在所述第一和第三單元,下一步按鈕的下方。 這不是一個乾淨的解決方案,主要是爲了演示問題而創建的。

gbc.fill = GridBagConstraints.NONE; 
gbc.gridwidth = 1; 
gbc.weighty = 0; 
gbc.weightx = 0; 
gbc.gridx = 0; 
gbc.gridy = 3; 
add(new JLabel(" "), gbc); 

gbc.gridx = 2; 
gbc.gridy = 3; 
add(new JLabel(" "), gbc); 

創建了兩個虛擬標籤。這些標籤的寬度決定了左側和右側間隙的寬度 。

溶液2

package com.zetcode; 

import java.awt.BorderLayout; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextArea; 

public class FillingCards2 extends JPanel { 

    private JTextArea question; 
    private JTextArea answer; 
    private JButton button; 
    private JLabel label; 


    public FillingCards2() { 


     setupGUI(); 
    } 

    private void setupGUI() { 

     question = new JTextArea(12, 22); 
     answer = new JTextArea(12, 22); 
     button = new JButton("Next"); 
     label = new JLabel("Answer"); 

     question.setBorder(
       BorderFactory.createEtchedBorder() 
     ); 

     answer.setBorder(
       BorderFactory.createEtchedBorder() 
     );   

     setLayout(new GridBagLayout()); 

     GridBagConstraints gbc = new GridBagConstraints(); 

     gbc.fill = GridBagConstraints.BOTH; 

     gbc.weightx = 1; 
     gbc.weighty = 1; 
     gbc.insets = new Insets(5, 15, 5, 15); 

     gbc.gridx = 1; 
     gbc.gridy = 0; 
     add(question, gbc); 

     gbc.anchor = GridBagConstraints.WEST; 
     gbc.fill = GridBagConstraints.NONE; 
     gbc.gridx = 1; 
     gbc.gridy = 1; 
     gbc.weighty = 0; 
     gbc.weightx = 0; 
     add(label, gbc); 

     gbc.fill = GridBagConstraints.BOTH; 
     gbc.gridx = 1; 
     gbc.gridy = 2; 
     gbc.weightx = 1; 
     gbc.weighty = 1; 
     add(answer, gbc); 

     gbc.insets.left = 5; 
     gbc.insets.right = 5; 
     gbc.gridwidth = 3; 
     gbc.weightx = 1; 
     gbc.weighty = 0; 
     gbc.gridx = 0; 
     gbc.gridy = 3; 
     gbc.fill = GridBagConstraints.HORIZONTAL; 
     add(button, gbc); 

    } 

    public static void main(String[] args) { 

     JFrame frame = new JFrame("Quiz cards"); 
     FillingCards2 card = new FillingCards2(); 
     frame.add(BorderLayout.CENTER, card); 
     frame.pack(); 
     frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    }  
} 

在這個例子中,我們使用insets屬性來創建所需 佈局。標籤和文本區域的左側和右側插入符號更寬,即那些按鈕。

gbc.insets.left = 5; 
gbc.insets.right = 5; 
gbc.gridwidth = 3; 
gbc.weightx = 1; 
gbc.weighty = 0; 
gbc.gridx = 0; 
gbc.gridy = 3; 
gbc.fill = GridBagConstraints.HORIZONTAL; 
add(button, gbc); 

左右插槽從15px更改爲5px。這樣我們實現了 該按鈕比其他組件寬。

溶液3

第三溶液用MigLayout管理器創建。我們需要較少的 代碼來創建佈局。

package com.zetcode; 

import java.awt.EventQueue; 
import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JTextArea; 
import net.miginfocom.swing.MigLayout; 


public class MigLayoutFillingCards extends JFrame { 

    public MigLayoutFillingCards() { 

     initUI(); 

     setTitle("Quiz cards"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setLocationRelativeTo(null); 
    } 


    private void initUI() { 

     setLayout(new MigLayout("wrap")); 

     JTextArea area1 = new JTextArea(); 
     JTextArea area2 = new JTextArea(); 

     area1.setBorder(
       BorderFactory.createEtchedBorder() 
     ); 

     area2.setBorder(
       BorderFactory.createEtchedBorder() 
     );     

     JLabel label = new JLabel("Answer"); 
     JButton btn = new JButton("Next"); 

     add(area1, "w 250, h 150, grow, push, gap 15 15 0 0"); 
     add(label, "gap 15 15 0 0"); 
     add(area2, "w 250, h 150, grow, push, gap 15 15 0 0"); 
     add(btn, "growx, pushx"); 

     pack(); 
    } 

    public static void main(String[] args) { 

     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       MigLayoutFillingCards ex = new MigLayoutFillingCards(); 
       ex.setVisible(true); 
      } 
     }); 
    } 
} 

所需的佈局用gap約束,這增加了額外的空間 到組件的側面產生。

0

簡而言之 - gbc.gridwidth是允許組件跨越多個列的參數。例如,如果您有3列4行,並且您希望標籤佔據整個頂行,那麼您需要爲標籤分配第一個單元格。並設置gbc.gridwidth = 3;