#java #swing #alignment #layout-manager
#java #качать #выравнивание #макет-менеджер
Вопрос:
Я работаю над программой Battleship, и я столкнулся с небольшой ошибкой. Я хочу обозначить две сетки (пользовательскую и компьютерную), поэтому я использую GridBagLayout для управления размером компонентов. Теперь, когда я иду к центру текста, чтобы поместить его в середину метки, в которой он находится, он ничего не делает, он остается на том же месте. Вот мой код:
package buttongrid;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
public class ButtonGrid {
JFrame frame=new JFrame(); //creates frame
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JPanel panel3 = new JPanel();
JPanel panel4 = new JPanel();
JPanel panel5 = new JPanel();
JPanel panel6 = new JPanel();
JLabel label1 = new JLabel();
JLabel label2 = new JLabel();
JLabel[][] grid; //names the grid of buttons
JLabel[][] enemyGrid;
String COLS = "ABCDEFGHIJK";
GridBagConstraints c = new GridBagConstraints();
Border border = BorderFactory.createLineBorder(Color.BLACK, 1);
public ButtonGrid() throws MalformedURLException{ //constructor
URL urlPic = new URL("http://i47.tinypic.com/14wswi9.gif");
ImageIcon waterPic = new ImageIcon(urlPic);
frame.setLayout(new GridBagLayout()); //set layout
frame.setResizable(false);
//ADDING TOP LEFT PANEL
label1.setText("Your Grid");
label1.setHorizontalTextPosition(SwingConstants.CENTER);
label1.setVerticalTextPosition(SwingConstants.CENTER);
panel4.add(label1);
panel4.setBorder(border);
c.gridx = 0;
c.gridy = 0;
c.ipady = 10;
frame.add(panel4, c);
//ADDING TOP MIDDLE PANEL
panel5.setBorder(border);
c.gridx = 1;
c.gridy = 0;
c.ipady = 10;
frame.add(panel5, c);
//ADDING TOP MIDDLE PANEL
label2.setText("Enemy Grid");
label2.setHorizontalTextPosition(SwingConstants.CENTER);
label2.setVerticalTextPosition(SwingConstants.CENTER);
panel6.add(label2);
panel6.setBorder(border);
c.gridx = 2;
c.gridy = 0;
c.ipady = 10;
frame.add(panel6, c);
//USER GRID
c.gridx = 0;
c.gridy = 1;
panel1.setLayout(new GridLayout(11,11));
grid=new JLabel[11][11]; //allocate the size of grid
for(int y=0; y<11; y ){
for(int x=0; x<11; x ){
ImageIcon icon2 = new ImageIcon(new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB));
grid[x][y]= new JLabel(icon2);
grid[x][y].setBorder(border);
panel1.add(grid[x][y]);
}
}
frame.add(panel1, c);
for(int y=1; y<11; y ){
grid[y][0].setText(Integer.toString(y));
grid[y][0].setHorizontalTextPosition(SwingConstants.CENTER);
for(int x=1; x<11; x ){
grid[x][y].setIcon(waterPic);
}
}
for(int x = 1; x < 11; x ){
grid[0][x].setText(COLS.substring(x - 1, x));
grid[0][x].setHorizontalTextPosition(SwingConstants.CENTER);
}
//EMPTY SPACE IN BETWEEN GRIDS
c.fill = GridBagConstraints.VERTICAL;
c.gridx = 1;
c.gridy = 1;
c.ipadx = 10;
panel2.setBorder(border);
frame.add(panel2, c);
//ENEMY GRID
c.gridx = 2;
c.gridy = 1;
panel3.setLayout(new GridLayout(11,11));
enemyGrid=new JLabel[11][11]; //allocate the size of grid
for(int y=0; y<11; y ){
for(int x=0; x<11; x ){
ImageIcon icon2 = new ImageIcon(new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB));
enemyGrid[x][y]= new JLabel(icon2); //
enemyGrid[x][y].setBorder(border);
panel3.add(enemyGrid[x][y]); //
}
}
frame.add(panel3, c);
for(int y=1; y<11; y ){
enemyGrid[y][0].setText(Integer.toString(y));
enemyGrid[y][0].setHorizontalTextPosition(SwingConstants.CENTER);
for(int x=1; x<11; x ){
enemyGrid[x][y].setIcon(waterPic);
}
}
for(int x = 1; x < 11; x ){
enemyGrid[0][x].setText(COLS.substring(x - 1, x));
enemyGrid[0][x].setHorizontalTextPosition(SwingConstants.CENTER);
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack(); //sets appropriate size for frame
frame.setVisible(true); //makes frame visible
}
public static void main(String[] args) throws MalformedURLException{
new ButtonGrid();//makes new ButtonGrid with 2 parameters
}
}
Я включил рамку вокруг каждого компонента во фрейме, просто чтобы упростить задачу.
Ответ №1:
Я предполагаю, что вы имеете в виду метки заголовков…
Это вызвано диспетчером компоновки, а не самой меткой. JPanel
FlowLayout
по умолчанию используется a. Рассмотрите возможность использования другого менеджера компоновки, например, GridBagLayout
например
JPanel panel4 = new JPanel(new GridBagLayout());
JPanel panel6 = new JPanel(new GridBagLayout());
Если вам нужно больше отступов для меток, вы можете использовать a CompoundBorder
и смешать текущую границу с EmptyBorder
или использовать GridBagConstraints
для определения дополнительных вставок…
Например…
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(8, 8, 8, 8);
//...
panel4.add(label1, gbc);
//...
panel6.add(label2, gbc);
Вы можете получить лучший результат, хотя вы разбиваете пользовательский интерфейс на разделы. Сетка является повторяемым компонентом, поэтому начните с создания сетки в качестве собственного компонента.
Вы могли бы использовать a BorderLayout
для позиционирования заголовка и самой сетки, а затем, используя другой контейнер, добавить GridPanel
s, используя a GridLayout
, чтобы расположить их рядом, например…
Комментарии:
1. 1, для определения менеджера компоновки панелей как проблемы.
2. Ах, хорошо, я понимаю, я обязательно попробую это и посмотрю, работает ли это, спасибо!
Ответ №2:
Основываясь на предположении Mad о том, что проблема заключается в диспетчере компоновки панели, я бы сделал еще один шаг и сказал, что вам даже не нужна JPanel для хранения меток. Просто добавьте метки непосредственно в сетку, а затем вам даже нужно беспокоиться о панелях.
Вы можете управлять желаемым интервалом, используя рамку для каждой метки. Например, вы могли бы создать границу, подобную:
Border labelBorder = BorderFactory.createEmptyBorder(5, 10, 5, 10);
Тогда код для добавления метки в сетку будет:
label1.setBorder(labelBorder);
//panel4.add(label1);
//panel4.setBorder(border);
c.gridx = 0;
c.gridy = 0;
//c.ipady = 10;
//frame.add(panel4, c);
frame.add(label1, c);
Для среднего компонента вы можете просто создать JLabel без текста. Затем граница займет все пространство, которое будет контролировать горизонтальное пространство, которое у вас есть между двумя сетками.
Кроме того, нет необходимости создавать BufferedImages, чтобы использовать их в качестве значка. Размер сетки будет определяться размером вашего «водяного» изображения.
Для центрирования текста в сетке вы должны использовать следующий метод:
label.setHorizontalAlignment(SwingConstants.CENTER);
по умолчанию вертикальное выравнивание выполняется по центру, поэтому вам не нужно беспокоиться об этом.
Комментарии:
1. Что касается BufferedImages, я думаю, мне это нужно, так как строка чисел и столбец букв будут меньше, чем мне нужно, поэтому я установил для всего размер по умолчанию в сетке, поскольку больше ничего не изменится.
2. @user3741402, размер ячейки одинаков для всех ячеек в GridLayout. Самый большой компонент, добавленный в сетку, определяет размер всех ячеек в сетке.