Выравнивание текста в графическом интерфейсе

#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. Самый большой компонент, добавленный в сетку, определяет размер всех ячеек в сетке.