Java Swing - поля JPanel и GridLayout / отступы - PullRequest
3 голосов
/ 02 декабря 2010

Я работаю над созданием шахматной игры на Java, и в настоящее время у меня возникли некоторые проблемы с получением графического интерфейса в точности так, как я хочу с Swing.Я использую GridLayout для организации сетки 8x8 ChessButton с (которая переопределяет JButton, чтобы я мог хранить в них дополнительную информацию, такую ​​как координаты).Изначально ChessButton не появлялись бы, если бы я их не накрыл, но я решил эту проблему, поместив каждый ChessButton в отдельный JPanel и установив для каждой кнопки setPreferredSize() заданную высоту и ширину.*

Теперь моя проблема в том, что, кажется, есть небольшое поле или отступы над (и / или ниже?) Каждой кнопкой.Я установил setHgap(0) и setVgap(0) для GridLayout, так что я почти уверен, что таинственное поле исходит от кнопок или JPanel s.Но я не могу избавиться от них, и они, кажется, заставляют каждый ChessButton немного смещаться вверх / вниз всякий раз, когда я намыкаю на них.

Я понимаю это описание проблемыможет быть немного трудно визуализировать, поэтому я сделал снимок экрана (используя JButton с, а не ChessButton с, чтобы пропуски немного легче распознать): http://img3.imageshack.us/img3/6656/jbuttonmargins.png

Вот кодЯ использовал для инициализации каждого ChessButton:

    chessBoard = new JPanel(new GridLayout(8, 8, 0, 0));
    chessBoard.setBorder(BorderFactory.createEmptyBorder());

    for (int i = 0; i <= 65; i++) {
            //Create a new ChessButton
            ChessButton button = new ChessButton("hi");
            button.setBorder(BorderFactory.createEmptyBorder());
            button.setPreferredSize(new Dimension(75, 75));
            button.setMargin(new Insets(0, 0, 0, 0));

            //Create a new JPanel that the ChessButton will go into
            JPanel buttonPanel = new JPanel();
            buttonPanel.setPreferredSize(new Dimension(75, 75));
            buttonPanel.setBorder(BorderFactory.createEmptyBorder());
            buttonPanel.add(button);

            //Add the buttonPanel to the grid
            chessBoard.add(buttonPanel);
    }

Итак, как я могу избавиться от этих вертикальных пробелов между кнопками?Я относительно новичок в Swing, поэтому извините, если ответ чрезвычайно очевиден, но я был бы признателен за любую помощь, которую кто-либо может предложить!Заранее спасибо!

Ответы [ 3 ]

16 голосов
/ 02 декабря 2010

Не добавлять пустую рамку;используйте setBorderPainted(false).

Приложение: Как отмечает @camickr, макет панели может содержать пробелы по умолчанию.В приведенном ниже примере используется без пропуска GridLayout соответственно.

alt text

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

/** @see http://stackoverflow.com/questions/4331699 */
public class ButtonBorder extends JPanel {

    private static final int N = 8;
    private static final int SIZE = 75;

    public ButtonBorder() {
        super(new GridLayout(N, N));
        this.setPreferredSize(new Dimension(N * SIZE, N * SIZE));
        for (int i = 0; i < N * N; i++) {
            this.add(new ChessButton(i));
        }
    }

    private static class ChessButton extends JButton {

        public ChessButton(int i) {
            super(i / N + "," + i % N);
            this.setOpaque(true);
            this.setBorderPainted(false);
            if ((i / N + i % N) % 2 == 1) {
                this.setBackground(Color.gray);
            }
        }
    }

    private void display() {
        JFrame f = new JFrame("ButtonBorder");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ButtonBorder().display();
            }
        });
    }
}
3 голосов
/ 02 декабря 2010

Изначально кнопки ChessButton не появлялись, если бы я их не накрыл, но я решил эту проблему, поместив каждую кнопку ChessButton внутри отдельной JPanel и установив для каждой кнопки setPreferredSize () заданную высоту и ширину

Это не правильное решение. Нет никаких оснований использовать JPanel для удержания кнопок. На самом деле, это, вероятно, причина проблемы. Кнопки должны отображаться при добавлении их в GridLayout. Если они не отображаются, возможно, потому что вы добавили кнопки в графический интерфейс после того, как сделали видимым графический интерфейс. Компоненты должны быть добавлены в графический интерфейс, прежде чем он станет видимым.

Теперь моя проблема в том, что, кажется, есть небольшое поле или отступ над (и / или ниже?) Каждой кнопкой

Я не понимаю, почему также нет горизонтального зазора. Когда вы создаете JPanel, по умолчанию он использует FlowLayout, который также содержит горизонтальный / вертикальный разрыв 5 пикселей. Так что я понимаю, почему у вас может быть вертикальный зазор 10 пикселей. Я не понимаю, почему нет горизонтального разрыва.

Если вам нужна дополнительная помощь, опубликуйте SSCCE , демонстрирующую проблему. И SSCCE должен использовать обычные кнопки J. Перед началом работы с пользовательскими компонентами ознакомьтесь с основами работы со стандартными компонентами. Таким образом, вы узнаете, связана ли проблема с вашим пользовательским кодом или нет.

1 голос
/ 02 декабря 2010

Попробуйте добавить chessBoard.setPreferredSize (600, 600), чтобы создать JPanel для доски, в которой есть место только для кнопок (8 кнопок в каждую сторону * 75 размеров в каждую сторону на кнопках).

...