Я создаю шахматную игру, в которой главная панель использует BorderLayout, на панели NORTH
есть панель для кнопок, панель в CENTER
для самой платы (установлена в GridLayout) и боковая панель на East
.
Я сделал JFrame неустранимым, и я бы хотел, чтобы шахматная доска соответствовала панелям так, чтобы East
панель была намного шире (может быть, 200 пикселей), и board
остается квадратом. Я не могу понять, как изменить размеры этих компонентов по отдельности.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class GameWindow extends JFrame {
private final JPanel playArea = new JPanel(new BorderLayout(3,3));
private final JButton[][] boardSquares = new JButton[8][8];
private final JPanel board;
private final JPanel sidebar = new JPanel();
private final JLabel message = new JLabel("Game by ...");
public GameWindow() {
playArea.setBorder(new EmptyBorder(5, 5, 5, 5));
JToolBar tools = new JToolBar();
tools.setFloatable(false);
playArea.add(tools, BorderLayout.PAGE_START);
tools.add(new JButton("New Game"));
tools.add(new JButton("Save"));
tools.add(new JButton("Restore"));
tools.addSeparator();
tools.add(new JButton("Resign"))
tools.addSeparator();
tools.add(message);
board = new JPanel(new GridLayout(0, 8));
board.setBorder(new LineBorder(Color.BLACK));
playArea.add(board, BorderLayout.CENTER);
playArea.add(sidebar, BorderLayout.EAST);
Insets buttonMargin = new Insets(0,0,0,0);
for (int i = 0; i < boardSquares.length; i++) {
for (int j = 0; j < boardSquares[i].length; j++) {
JButton square = new JButton();
square.setMargin(buttonMargin);
if ((i+j)%2 == 0) {
square.setBackground(Color.WHITE);
}
else {
square.setBackground(Color.BLACK);
}
board.setSize(600, 600);
board.add(boardSquares[j][i] = square);
}
}
}
public final JComponent getChessBoard() {
return board;
}
public final JComponent getGui() {
return playArea;
}
public static void main(String[] args) {
GameWindow window = new GameWindow();
JFrame frame = new JFrame("Checkers");
frame.setResizable(false);
frame.add(window.getGui());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setSize(800, 800);
frame.setVisible(true);
}
}
Во-первых, с JDK 1.4 Java поощряет использование констант BorderLayout
как BorderLayout.PAGE_START
, BorderLayout.LINE_START
, BorderLayout.CENTER
, BorderLayout.LINE_END
и BorderLayout.PAGE_END
сравнению с последним, используемым вами.
Во-вторых, вы можете просто переопределить getPreferredSize() указанного JPanel
, чтобы он мог дать, какой-то размер, который вы чувствуете, будет работать для вашего прецедента. Использование setPreferredSize()
ограничено, так как не все LayoutManagers используют для соблюдения указанного в нем измерения.
Следовательно, вы можете сделать что-то вроде:
private final JPanel sidebar = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
};
Вы можете попробовать этот модифицированный код:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class GameWindow extends JFrame {
private final JPanel playArea = new CustomPanel(710, 710);
private final JButton[][] boardSquares = new JButton[8][8];
private final JPanel board;
private final JPanel sidebar = new CustomPanel(100, 100);
private final JLabel message = new JLabel("Game by ...");
public GameWindow() {
playArea.setLayout(new BorderLayout(3,3));
playArea.setBorder(new EmptyBorder(5, 5, 5, 5));
JToolBar tools = new JToolBar();
tools.setFloatable(false);
playArea.add(tools, BorderLayout.PAGE_START);
tools.add(new JButton("New Game"));
tools.add(new JButton("Save"));
tools.add(new JButton("Restore"));
tools.addSeparator();
tools.add(new JButton("Resign"));
tools.addSeparator();
tools.add(message);
board = new CustomPanel(600, 600);
board.setLayout(new GridLayout(0, 8));
board.setBorder(new LineBorder(Color.BLACK));
playArea.add(board, BorderLayout.CENTER);
playArea.add(sidebar, BorderLayout.LINE_START);
Insets buttonMargin = new Insets(0,0,0,0);
for (int i = 0; i < boardSquares.length; i++) {
for (int j = 0; j < boardSquares[i].length; j++) {
JButton square = new JButton();
square.setOpaque(true);
square.setMargin(buttonMargin);
if ((i+j)%2 == 0) {
square.setBackground(Color.WHITE);
}
else {
square.setBackground(Color.BLACK);
}
board.add(boardSquares[j][i] = square);
}
}
}
private class CustomPanel extends JPanel {
private int width;
private int height;
public CustomPanel(int width, int height) {
this.width = width;
this.height = height;
setOpaque(true);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
}
public final JComponent getChessBoard() {
return board;
}
public final JComponent getGui() {
return playArea;
}
public static void main(String[] args) {
GameWindow window = new GameWindow();
JFrame frame = new JFrame("Checkers");
frame.setResizable(false);
frame.setContentPane(window.getGui());
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.pack();
frame.setVisible(true);
}
}
Более того, перед установкой фона JButton
было бы разумно вызвать button.setOpaque(true)
.
Нетрудно установить размер JPanel
. Просто вызовите setPreferredSize()
. В вашем случае, чтобы изменить размер вашего восточного JPanel
, позвоните:
sidebar.setPreferredSize(new Dimension(200, 200));
После этого ваш LayoutManager
установит размер вашего JPanel
на LayoutManager
.
К вашему другому JPanel
, board
: невозможно сделать Component
(например, JPanel
), оставшийся квадратом. Они всегда вписываются в прямоугольники. Вам нужно будет создать свой собственный подкласс JComponent
и только нарисовать все на площади, оставив все прозрачным. Поэтому перезапишите метод JComponent.paintComponent(Graphics)
.
getPreferredSize
для JPanel
как было предложено? Я думаю, что это только больше кода с той же функцией
frame.setSize(800, 800);
вместоframe.pack();
?