GridBagLayout Не заставлять компоненты «прыгать» после добавления - PullRequest
1 голос
/ 24 октября 2011

Я хочу использовать GridBagLayout для макета с <= 3 столбцами и переменным количеством строк (если кто-нибудь знает другой макет, который может легко это сделать, скажите мне), каждый раз, когда я нажимаю кнопку «Добавить»,квадрат будет добавлен в первом доступном месте.Примерно так: </p>

|x x x|
|x x x|
|x o  |

Х - это квадраты, и когда я нажимаю кнопку добавления, нужно добавить новый квадрат, где сейчас находится o.Мне удалось «сделать так, чтобы это работало» примерно так:

public void addSquare(Square square) {
    c.fill = GridBagConstraints.NONE;
    c.gridx = nrOfSquares % 3;
    c.gridy = (int) (nrOfSquares / 3);
    c.weighty = 1;
    c.weightx = 1;
    c.anchor = GridBagConstraints.NORTHWEST;
    c.insets = new Insets(5, 5, 5, 5);
    this.container.add(square, c);
    this.container.revalidate();
    ++nrOfSquares;
}

проблема в том, что добавляется второй квадрат, который я добавляю так:

|x  x  |

пожалуйста, обратите внимание, что естьдополнительное пространство между первым квадратом и вторым.У меня та же проблема, когда добавляется дополнительная строка.

Теперь, как мне исправить мой код, чтобы квадраты не "перепрыгивали" и добавлялись, как в первом примере, который я дал?

РЕДАКТИРОВАТЬ: по запросу, лучший пример после того, как я преобразовал его в обычный GridLayout:

public class Square extends JPanel {
   public Square() {
       super();     
       Dimension SIZE = new Dimension(200, 200);
       this.setSize(SIZE);
       this.setPreferredSize(SIZE);
       this.setMinimumSize(SIZE);
       this.setMaximumSize(SIZE);

       this.setBackground(Color.ORANGE);

       this.setVisible(true);
   }
}

public class SquareContainer extends JPanel {
    protected JPanel realContainer;

    public SquareContainer(int width, int height) {
        super();
        this.setLayout(new BorderLayout());
        this.setBackground(Color.WHITE);
        this.setSize(width, height);
        this.realContainer = new JPanel();
        GridLayout layout = new GridLayout(0, 3);
        layout.setHgap(10);
        layout.setVgap(10);
        this.realContainer.setLayout(layout);
        this.realContainer.setBackground(this.getBackground());
        JScrollPane scroller = new JScrollPane(this.realContainer);
        scroller.getVerticalScrollBar().setUnitIncrement(20);
        this.add(scroller, BorderLayout.CENTER);
    }

    public void addSquare(Square square) {
        this.realContainer.add(square);
        this.realContainer.revalidate();
    }
}

И я просто добавляю это в JFrame:

public class TheGreatFrame extends JFrame {
    public TheGreatFrame() {
        super();
        this.setSize(800, 800);
        this.setLocationRelativeTo(null);
        this.setLayout(new BorderLayout());
        this.setResizable(false);

        this.add(new SquareContainer(750, 660), BorderLayout.CENTER);

        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.setVisible(true);
    }
}

Ответы [ 2 ]

4 голосов
/ 24 октября 2011

Небольшой пример программы использования GridLayout:

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

public class GridLayoutEg {

   private static void createAndShowGui() {
      final JPanel centerPanel = new JPanel(new GridLayout(0, 3)); 

      JButton addBtn = new JButton(new AbstractAction("Add Button") {

         @Override
         public void actionPerformed(ActionEvent e) {
            centerPanel.add(new JButton("X"));
            centerPanel.revalidate();
            centerPanel.repaint();  

            SwingUtilities.getWindowAncestor(centerPanel).pack();
         }
      });
      JPanel btnPanel = new JPanel();
      btnPanel.add(addBtn);

      JPanel mainPanel = new JPanel(new BorderLayout());
      mainPanel.add(centerPanel, BorderLayout.CENTER);
      mainPanel.add(btnPanel, BorderLayout.PAGE_END);
      JFrame frame = new JFrame("GridLayoutEg");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
2 голосов
/ 24 октября 2011

, если все JComponents могут иметь одинаковые HEIGHT и WEIGHT, ищите GridLayout

в случае, если JComponent не может совпадать WEIGHT, затем ставьте"line" в отдельный JPanel (используя BorderLayout или BoxLayout) и используйте GridLayout для помещения этих JPanels в Container

...