2014-09-28 10 views
8

Я пытаюсь использовать GridBagLayout, но я не понимаю, что я ожидал, и я не могу найти ошибку в этом коде:Java GridBagLayout не работает

public class GridBagEx1 extends JPanel { 

    private static final long serialVersionUID = 1L; 

    protected void makebutton(String name, GridBagLayout gridbag, GridBagConstraints c) { 
     JButton button = new JButton(name); 
     gridbag.setConstraints(button, c); 
     add(button); 
    } 

    public void init() { 
     GridBagLayout gridbag = new GridBagLayout(); 
     GridBagConstraints c = new GridBagConstraints(); 
     setLayout(gridbag); 

     c.fill = BOTH; 

     c.weightx = 1.0; 
     c.weighty = 1.0; 

     c.anchor = CENTER; 

     c.insets.top = 5; 
     c.insets.bottom = 5; 
     c.insets.left = 5; 
     c.insets.right = 5; 

     c.gridx = 0; 
     c.gridy = 0; 
     c.gridheight = 1; 
     c.gridwidth = 2; 
     makebutton("Button1", gridbag, c);  

     c.gridx = 2; 
     c.gridy = 0; 
     c.gridheight = 1; 
     c.gridwidth = 1; 
     makebutton("Button2", gridbag, c); 

     c.gridx = 3; 
     c.gridy = 0; 
     c.gridheight = 2; 
     c.gridwidth = 2; 
     makebutton("Button3", gridbag, c); 

     c.gridx = 0; 
     c.gridy = 1; 
     c.gridheight = 1; 
     c.gridwidth = 1; 
     makebutton("Button4", gridbag, c); 

     c.gridx = 1; 
     c.gridy = 1; 
     c.gridheight = 1; 
     c.gridwidth = 2; 
     makebutton("Button5", gridbag, c); 

     c.gridx = 0; 
     c.gridy = 2; 
     c.gridheight = 1; 
     c.gridwidth = 1; 
     makebutton("Button6", gridbag, c); 

     c.gridx = 1; 
     c.gridy = 2; 
     c.gridheight = 1; 
     c.gridwidth = 2; 
     makebutton("Button7", gridbag, c); 

     c.gridx = 3; 
     c.gridy = 2; 
     c.gridheight = 1; 
     c.gridwidth = 1; 
     makebutton("Button8", gridbag, c); 

     c.gridx = 4; 
     c.gridy = 2; 
     c.gridheight = 1; 
     c.gridwidth = 1; 
     makebutton("Button9", gridbag, c); 
    } 

    public static void main(String args[]) { 
     JFrame frame = new JFrame(); 
     GridBagEx1 ex1 = new GridBagEx1(); 

     ex1.init(); 

     frame.add(ex1); 
     frame.pack(); 
     frame.setVisible(true); 
    } 
} 

Эта фотография иллюстрировать то, что мне нужно:

Programmers love paint

Желтый: имя кнопки, красный являются строки и столбцы.

Это то, что происходит на самом деле: Whats wrong here?

Может кто-нибудь объяснить, что неправильно в моем коде?

+4

Я не могу объяснить этот вопрос пока нет, но приходится констатировать, что ваш вопрос очень хорошо представлен , спасибо и 1+. –

+0

@HovercraftFullOfEels Спасибо – Emax

+0

'c.fill = BOTH;' должен быть 'c.fill = GridBagConstraints.BOTH;' и тот же для 'c.anchor = CENTER;' для компиляции кода. – user1803551

ответ

6

Проблема заключается в том, что ничто не убеждает второй столбец сетки (gridx = 1) иметь любую ширину, поскольку нет компонента, который должен соответствовать только во втором столбце. Второй столбец, таким образом, имеет ширину 0, поэтому, хотя Button1 перемещает первые два столбца, это выглядит не так, потому что вся его ширина нуждается в первом столбце; и хотя Button5 и Button7 располагают второй и третий столбцы, все их ширины удовлетворяются третьим столбцом.

Чтобы исправить это, вы должны убедить кнопки, которые должны быть более широкими (1, 5, 7), чтобы заняться больше места. Здесь я добавил добавление к этим кнопкам, установив c.ipadx = 35;. (Я также удалил weightx = 1.0 ограничения По причинам, я не совсем понимаю, это не сработало, когда это было оставлено в.).:

screenshot

Источник:

public void init() { 
    GridBagLayout gridbag = new GridBagLayout(); 
    GridBagConstraints c = new GridBagConstraints(); 
    setLayout(gridbag); 

    c.fill = c.BOTH; 

    //c.weightx = 1.0; 
    //c.weighty = 1.0; 

    c.anchor = c.CENTER; 

    c.insets.top = 5; 
    c.insets.bottom = 5; 
    c.insets.left = 5; 
    c.insets.right = 5; 

    c.gridx = 0; 
    c.gridy = 0; 
    c.gridheight = 1; 
    c.gridwidth = 2; 
    c.ipadx = 35; 
    makebutton("Button1", gridbag, c); 

    c.gridx = 2; 
    c.gridy = 0; 
    c.gridheight = 1; 
    c.gridwidth = 1; 
    c.ipadx = 0; 
    makebutton("Button2", gridbag, c); 

    c.gridx = 3; 
    c.gridy = 0; 
    c.gridheight = 2; 
    c.gridwidth = 2; 
    c.ipadx = 0; 
    makebutton("Button3", gridbag, c); 

    c.gridx = 0; 
    c.gridy = 1; 
    c.gridheight = 1; 
    c.gridwidth = 1; 
    c.ipadx = 0; 
    makebutton("Button4", gridbag, c); 

    c.gridx = 1; 
    c.gridy = 1; 
    c.gridheight = 1; 
    c.gridwidth = 2; 
    c.ipadx = 35; 
    makebutton("Button5", gridbag, c); 

    c.gridx = 0; 
    c.gridy = 2; 
    c.gridheight = 1; 
    c.gridwidth = 1; 
    c.ipadx = 0; 
    makebutton("Button6", gridbag, c); 

    c.gridx = 1; 
    c.gridy = 2; 
    c.gridheight = 1; 
    c.gridwidth = 2; 
    c.ipadx = 35; 
    makebutton("Button7", gridbag, c); 

    c.gridx = 3; 
    c.gridy = 2; 
    c.gridheight = 1; 
    c.gridwidth = 1; 
    c.ipadx = 0; 
    makebutton("Button8", gridbag, c); 

    c.gridx = 4; 
    c.gridy = 2; 
    c.gridheight = 1; 
    c.gridwidth = 1; 
    c.ipadx = 0; 
    makebutton("Button9", gridbag, c); 
} 

Редактировать: Как указано в комментариях, вышеупомянутый подход не подходит, поскольку он предотвращает динамическое изменение макета. Чтобы развернуть макет, чтобы заполнить размер его контейнера, необходимы ограничения weightx и weighty, но затем второй столбец не получает никакой ширины.

Купить данный продукт в категории альтернатива решение. Это грязный хак, который вставляет невидимый компонент в нижней части второй колонны, чтобы заставить колонку, чтобы иметь ширину:

c.gridx = 1; 
    c.gridy = 3; 
    c.gridheight = 1; 
    c.gridwidth = 1; 
    c.insets.set(0, 0, 0, 0); 
    c.weighty = 0; 
    add(Box.createRigidArea(new Dimension(50, 0)), c); 

Это справляется достаточно хорошо, когда окно изменяется, поскольку, хотя компонент дается фиксированный начальный размер , GridBagLayout масштабирует его пропорционально другим компонентам. Тем не менее, это все еще не идеально. Может быть, есть лучшее решение, но я не могу его найти.

+0

Могу ли я увидеть исходный код? – Emax

+0

@ FilipB.Vondrášek Я не думаю, что это один конкретный случай с конкретным (довольно сложным) менеджером макетов _sums up_ и оправдывает свинг, являющийся мерзостью. У Sure Swing есть свои минусы и плюсы, но это не похоже на секрет, все это знают. – icza

+0

@ Emax добавлен – Boann

2

мне удалось разработать необходимый макет без хака и поддерживающего динамического изменения размера с помощью JGoodies FormLayout:

import java.awt.Component; 

import javax.swing.JButton; 
import javax.swing.JPanel; 

import com.jgoodies.forms.factories.FormFactory; 
import com.jgoodies.forms.layout.ColumnSpec; 
import com.jgoodies.forms.layout.FormLayout; 
import com.jgoodies.forms.layout.RowSpec; 

public class FormLayoutPanel extends JPanel 
    { 
    public FormLayoutPanel() 
     { 
     setAlignmentY(Component.BOTTOM_ALIGNMENT); 
     setAlignmentX(Component.RIGHT_ALIGNMENT); 
     setLayout(new FormLayout(new ColumnSpec[] { 
      ColumnSpec.decode("41px:grow"), 
      FormFactory.LABEL_COMPONENT_GAP_COLSPEC, 
      ColumnSpec.decode("25px:grow"), 
      FormFactory.LABEL_COMPONENT_GAP_COLSPEC, 
      ColumnSpec.decode("41px:grow"), 
      FormFactory.LABEL_COMPONENT_GAP_COLSPEC, 
      ColumnSpec.decode("41px:grow"), 
      FormFactory.LABEL_COMPONENT_GAP_COLSPEC, 
      ColumnSpec.decode("41px:grow"), }, 
      new RowSpec[] { 
       RowSpec.decode("25px:grow"), 
       FormFactory.LINE_GAP_ROWSPEC, 
       RowSpec.decode("25px:grow"), 
       FormFactory.LINE_GAP_ROWSPEC, 
       RowSpec.decode("25px:grow"), })); 

     JButton button1 = new JButton("1"); 
     add(button1, "1, 1, 3, 1, fill, fill"); 
     JButton button2 = new JButton("2"); 
     add(button2, "5, 1, fill, fill"); 
     JButton button3 = new JButton("3"); 
     add(button3, "7, 1, 3, 3, fill, fill"); 
     JButton button4 = new JButton("4"); 
     add(button4, "1, 3, fill, fill"); 
     JButton button5 = new JButton("5"); 
     add(button5, "3, 3, 3, 1, fill, fill"); 
     JButton button6 = new JButton("6"); 
     add(button6, "1, 5, fill, fill"); 
     JButton button7 = new JButton("7"); 
     add(button7, "3, 5, 3, 1, fill, fill"); 
     JButton button8 = new JButton("8"); 
     add(button8, "7, 5, fill, fill"); 
     JButton button9 = new JButton("9"); 
     add(button9, "9, 5, fill, fill"); 
     } 
    } 
+0

Я попробую это решение, спасибо за помощь! – Emax

Смежные вопросы