Box Layout перемещает компоненты, выравнивание

Я хотел бы создать следующий графический интерфейс:

https://www.dropbox.com/s/ebm057jfevwe532/result.png?dl=0

Вот мой код:

public class TypingTutor extends JFrame{
private JPanel mainPanel;
private JPanel[] keyboardPanel;
private JLabel instructionsLabel;
private JLabel noteLabel;
private JTextArea typingTextArea;
private JButton[] buttonKeysFirstRow;
private JButton[] buttonKeysSecondRow;
private JButton[] buttonKeysThirdRow;
private JButton[] buttonKeysFourthRow;
private JButton[] buttonKeysFifthRow;
//TypingTutor no-argument constructor
public TypingTutor(){
    super("Typing Application");
    setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));

    instructionsLabel = new JLabel("Type some text using your keyboard. The keys you press " +
        "will be highlighted and the text will be displayed.");
    noteLabel = new JLabel("Note: Clicking the buttons with your mouse will not perform any " +
        "action.");
    add(instructionsLabel);
    add(noteLabel);

    typingTextArea = new JTextArea();
    add(typingTextArea);

    //each row represents each row in the keyboard
    buttonKeysFirstRow = new JButton[14];
    buttonKeysSecondRow = new JButton[13];
    buttonKeysThirdRow = new JButton[14];
    buttonKeysFourthRow = new JButton[12];
    buttonKeysFifthRow = new JButton[4];
    initializeKeys(1);
    initializeKeys(2);
    initializeKeys(3);
    initializeKeys(4);
    initializeKeys(5);
    Box[] keyboard = new Box[5];
    for(int i = 0; i < keyboard.length; i++){
        keyboard[i] = Box.createHorizontalBox();
        switch(i){
            case 0:
                for(int j = 0; j < buttonKeysFirstRow.length; j++){
                    keyboard[i].add(buttonKeysFirstRow[j]);
                } //end for
                break;
            case 1:
                for(int j = 0; j < buttonKeysSecondRow.length; j++){
                    keyboard[i].add(buttonKeysSecondRow[j]);
                } //end for
                break;
            case 2:
                for(int j = 0; j < buttonKeysThirdRow.length; j++){
                        keyboard[i].add(buttonKeysThirdRow[j]);
                } //end for
                break;
            case 3:
                for(int j = 0; j < buttonKeysFourthRow.length; j++){
                    keyboard[i].add(buttonKeysFourthRow[j]);
                } //end for
                break;
            case 4:
                for(int j = 0; j < buttonKeysFifthRow.length; j++){
                    keyboard[i].add(buttonKeysFifthRow[j]);
                } //end for
                break;
        } //end switch
        add(keyboard[i]);
    } //end for
} //end TypingTutor no-argument constructor

//initializes button keys with their values
private void initializeKeys(int keys){
    switch(keys){
        case 1:
            buttonKeysFirstRow[0] = new JButton("|\n°");
            buttonKeysFirstRow[1] = new JButton("1");
            buttonKeysFirstRow[2] = new JButton("2");
            buttonKeysFirstRow[3] = new JButton("3");
            buttonKeysFirstRow[4] = new JButton("4");
            buttonKeysFirstRow[5] = new JButton("5");
            buttonKeysFirstRow[6] = new JButton("6");
            buttonKeysFirstRow[7] = new JButton("7");
            buttonKeysFirstRow[8] = new JButton("8");
            buttonKeysFirstRow[9] = new JButton("9");
            buttonKeysFirstRow[10] = new JButton("0");
            buttonKeysFirstRow[11] = new JButton("'\n?");
            buttonKeysFirstRow[12] = new JButton("¿\n¡");
            buttonKeysFirstRow[13] = new JButton("Backspace");
            break;
        case 2:
            buttonKeysSecondRow[0] = new JButton("  Tab  ");
            buttonKeysSecondRow[1] = new JButton("Q");
            buttonKeysSecondRow[2] = new JButton("W");
            buttonKeysSecondRow[3] = new JButton("E");
            buttonKeysSecondRow[4] = new JButton("R");
            buttonKeysSecondRow[5] = new JButton("T");
            buttonKeysSecondRow[6] = new JButton("Y");
            buttonKeysSecondRow[7] = new JButton("U");
            buttonKeysSecondRow[8] = new JButton("I");
            buttonKeysSecondRow[9] = new JButton("O");
            buttonKeysSecondRow[10] = new JButton("P");
            buttonKeysSecondRow[11] = new JButton("´\n¨");
            buttonKeysSecondRow[12] = new JButton("+\n*");
            break;
        case 3:
            buttonKeysThirdRow[0] = new JButton("  Caps  ");
            buttonKeysThirdRow[1] = new JButton("A");
            buttonKeysThirdRow[2] = new JButton("S");
            buttonKeysThirdRow[3] = new JButton("D");
            buttonKeysThirdRow[4] = new JButton("F");
            buttonKeysThirdRow[5] = new JButton("G");
            buttonKeysThirdRow[6] = new JButton("H");
            buttonKeysThirdRow[7] = new JButton("J");
            buttonKeysThirdRow[8] = new JButton("K");
            buttonKeysThirdRow[9] = new JButton("L");
            buttonKeysThirdRow[10] = new JButton("Ñ");
            buttonKeysThirdRow[11] = new JButton("{\n[");
            buttonKeysThirdRow[12] = new JButton("}\n]");
            buttonKeysThirdRow[13] = new JButton(" Enter ");
            break;
        case 4:
            buttonKeysFourthRow[0] = new JButton("   Shift   ");
            buttonKeysFourthRow[1] = new JButton("<\n>");
            buttonKeysFourthRow[2] = new JButton("Z");
            buttonKeysFourthRow[3] = new JButton("X");
            buttonKeysFourthRow[4] = new JButton("C");
            buttonKeysFourthRow[5] = new JButton("V");
            buttonKeysFourthRow[6] = new JButton("B");
            buttonKeysFourthRow[7] = new JButton("N");
            buttonKeysFourthRow[8] = new JButton("M");
            buttonKeysFourthRow[9] = new JButton(",\n;");
            buttonKeysFourthRow[10] = new JButton(".\n:");
            buttonKeysFourthRow[11] = new JButton("^");
            break;
        case 5:
            buttonKeysFifthRow[0] = new JButton("");
            buttonKeysFifthRow[1] = new JButton("<");
            buttonKeysFifthRow[2] = new JButton("v");
            buttonKeysFifthRow[3] = new JButton(">");

            buttonKeysFifthRow[0].setMinimumSize(new Dimension(50, 10));
            break;
    } //end switch
  } //end method initializeKeys
} //end class TypingTutor

И вот мой результат:

https://www.dropbox.com/s/dx99npirnl0v1wd/sample.png?dl=0

Я попытался использовать класс javax.swing.Box и добавить основной блок с Box.createVerticalBox() в центр в JFrame BorderLayout, а затем добавить другие блоки с помощью Box.createHorizontalBox(), и я получаю тот же результат, все в порядке пока я не добавлю JButtons после JTextArea, после этого JButtons сжимается, а JLabel выравнивается вправо.


person Dazt    schedule 08.01.2015    source источник
comment
Правильно ли я предполагаю, что у вас есть URL-адреса ваших изображений задом наперёд? Похоже, что первый - ваш фактический результат, а второй - желаемый результат.   -  person VGR    schedule 08.01.2015
comment
Ваши ссылки неправильные? Тот, который, по твоим словам, тебе нужен, кажется хуже того, который, по твоим словам, у тебя есть.   -  person J Richard Snape    schedule 08.01.2015
comment
Да, извините, ссылки обратные   -  person Dazt    schedule 10.01.2015


Ответы (2)


Неинтуитивно — вы сталкиваетесь с проблемой выравнивания меток по умолчанию. Это становится очевидным, когда вы комбинируете метки с некоторыми другими компонентами в BoxLayout — см. учебник по Java на странице выравнивание в BoxLayout

Попробуйте это для своих JLabels (обратите внимание на две новые строки):

instructionsLabel = new JLabel("Type some text using your keyboard. The keys you press " +
   "will be highlighted and the text will be displayed.");
noteLabel = new JLabel("Note: Clicking the buttons with your mouse will not perform any " +
    "action.");
instructionsLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
noteLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
add(instructionsLabel);
add(noteLabel);

Возможно, вам придется немного поэкспериментировать, чтобы правильно подобрать размер клавиши пробела — на моем компьютере размер экрана 50 x 10 очень мал…

ИЗМЕНИТЬ:

На самом деле маленькое отображение пробела также является проблемой при рисовании JButtons - см. этот вопрос . Таким образом, вы должны установить минимальный и предпочтительный размер, а затем максимальный размер, чтобы убедиться, что он проверяет минимальный размер и правильно рисует. Итак, замените ваш .setMinimumSize(... следующим (размеры 250 x 26 хорошо работали на моем дисплее)

        Dimension spaceDimension = new Dimension(250, 26);
        buttonKeysFifthRow[0].setMinimumSize(spaceDimension);
        buttonKeysFifthRow[0].setPreferredSize(spaceDimension);
        buttonKeysFifthRow[0].setMaximumSize(spaceDimension);
person J Richard Snape    schedule 08.01.2015
comment
Это на самом деле очень сработало. Теперь мне просто нужно установить предпочтительный размер для jbuttons, большое спасибо - person Dazt; 10.01.2015
comment
Нет проблем - будем признательны, если вы примете / проголосуете за ответ. - person J Richard Snape; 11.01.2015
comment
Я пытался, но он говорит, что у меня как минимум 15 репутации. - person Dazt; 16.01.2015
comment
Вы приняли это. Спасибо :) для голосования нужно 15 повторений, вы скоро получите это, если вы используете SO несколько раз - person J Richard Snape; 16.01.2015

Я внес некоторые изменения в ваш код, чтобы сделать его работоспособным. Вот изображение графического интерфейса преподавателя набора текста.

Репетитор по набору текста

Я отцентрировал текст инструкции, сделал область ввода разумного размера и поместил область ввода в область прокрутки. Я немного поправил пробел.

Вот исполняемый код.

package com.ggl.testing;

import java.awt.Dimension;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class TypingTutor extends JFrame {

    private static final long serialVersionUID = -7372491882460254385L;

    private JLabel instructionsLabel;
    private JLabel noteLabel;
    private JTextArea typingTextArea;
    private JButton[] buttonKeysFirstRow;
    private JButton[] buttonKeysSecondRow;
    private JButton[] buttonKeysThirdRow;
    private JButton[] buttonKeysFourthRow;
    private JButton[] buttonKeysFifthRow;

    // TypingTutor no-argument constructor
    public TypingTutor() {
        super("Typing Application");
        setLocationByPlatform(true);
        setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));

        JPanel instructionPanel = new JPanel();
        instructionPanel.setLayout(
                new BoxLayout(instructionPanel, BoxLayout.PAGE_AXIS));

        instructionsLabel = new JLabel(
                "Type some text using your keyboard. The keys you press "
                        + "will be highlighted and the text will be displayed.");
        instructionsLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
        instructionPanel.add(instructionsLabel);
        noteLabel = new JLabel(
                "Note: Clicking the buttons with your mouse will not perform any "
                        + "action.");
        noteLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
        instructionPanel.add(noteLabel);
        add(instructionPanel);

        typingTextArea = new JTextArea(10, 60);
        typingTextArea.setWrapStyleWord(true);
        JScrollPane scrollPane = new JScrollPane(typingTextArea);
        add(scrollPane);

        // each row represents each row in the keyboard
        buttonKeysFirstRow = new JButton[14];
        buttonKeysSecondRow = new JButton[13];
        buttonKeysThirdRow = new JButton[14];
        buttonKeysFourthRow = new JButton[12];
        buttonKeysFifthRow = new JButton[4];
        initializeKeys(1);
        initializeKeys(2);
        initializeKeys(3);
        initializeKeys(4);
        initializeKeys(5);
        Box[] keyboard = new Box[5];
        for (int i = 0; i < keyboard.length; i++) {
            keyboard[i] = Box.createHorizontalBox();
            switch (i) {
            case 0:
                for (int j = 0; j < buttonKeysFirstRow.length; j++) {
                    keyboard[i].add(buttonKeysFirstRow[j]);
                } // end for
                break;
            case 1:
                for (int j = 0; j < buttonKeysSecondRow.length; j++) {
                    keyboard[i].add(buttonKeysSecondRow[j]);
                } // end for
                break;
            case 2:
                for (int j = 0; j < buttonKeysThirdRow.length; j++) {
                    keyboard[i].add(buttonKeysThirdRow[j]);
                } // end for
                break;
            case 3:
                for (int j = 0; j < buttonKeysFourthRow.length; j++) {
                    keyboard[i].add(buttonKeysFourthRow[j]);
                } // end for
                break;
            case 4:
                for (int j = 0; j < buttonKeysFifthRow.length; j++) {
                    keyboard[i].add(buttonKeysFifthRow[j]);
                } // end for
                break;
            } // end switch
            add(keyboard[i]);
        } // end for
        this.pack();
        this.setVisible(true);

    } // end TypingTutor no-argument constructor

    // initializes button keys with their values
    private void initializeKeys(int keys) {
        switch (keys) {
        case 1:
            buttonKeysFirstRow[0] = new JButton("|\n°");
            buttonKeysFirstRow[1] = new JButton("1");
            buttonKeysFirstRow[2] = new JButton("2");
            buttonKeysFirstRow[3] = new JButton("3");
            buttonKeysFirstRow[4] = new JButton("4");
            buttonKeysFirstRow[5] = new JButton("5");
            buttonKeysFirstRow[6] = new JButton("6");
            buttonKeysFirstRow[7] = new JButton("7");
            buttonKeysFirstRow[8] = new JButton("8");
            buttonKeysFirstRow[9] = new JButton("9");
            buttonKeysFirstRow[10] = new JButton("0");
            buttonKeysFirstRow[11] = new JButton("'\n?");
            buttonKeysFirstRow[12] = new JButton("¿\n¡");
            buttonKeysFirstRow[13] = new JButton("Backspace");
            break;
        case 2:
            buttonKeysSecondRow[0] = new JButton("  Tab  ");
            buttonKeysSecondRow[1] = new JButton("Q");
            buttonKeysSecondRow[2] = new JButton("W");
            buttonKeysSecondRow[3] = new JButton("E");
            buttonKeysSecondRow[4] = new JButton("R");
            buttonKeysSecondRow[5] = new JButton("T");
            buttonKeysSecondRow[6] = new JButton("Y");
            buttonKeysSecondRow[7] = new JButton("U");
            buttonKeysSecondRow[8] = new JButton("I");
            buttonKeysSecondRow[9] = new JButton("O");
            buttonKeysSecondRow[10] = new JButton("P");
            buttonKeysSecondRow[11] = new JButton("´\n¨");
            buttonKeysSecondRow[12] = new JButton("+\n*");
            break;
        case 3:
            buttonKeysThirdRow[0] = new JButton("  Caps  ");
            buttonKeysThirdRow[1] = new JButton("A");
            buttonKeysThirdRow[2] = new JButton("S");
            buttonKeysThirdRow[3] = new JButton("D");
            buttonKeysThirdRow[4] = new JButton("F");
            buttonKeysThirdRow[5] = new JButton("G");
            buttonKeysThirdRow[6] = new JButton("H");
            buttonKeysThirdRow[7] = new JButton("J");
            buttonKeysThirdRow[8] = new JButton("K");
            buttonKeysThirdRow[9] = new JButton("L");
            buttonKeysThirdRow[10] = new JButton("Ñ");
            buttonKeysThirdRow[11] = new JButton("{\n[");
            buttonKeysThirdRow[12] = new JButton("}\n]");
            buttonKeysThirdRow[13] = new JButton(" Enter ");
            break;
        case 4:
            buttonKeysFourthRow[0] = new JButton("   Shift   ");
            buttonKeysFourthRow[1] = new JButton("<\n>");
            buttonKeysFourthRow[2] = new JButton("Z");
            buttonKeysFourthRow[3] = new JButton("X");
            buttonKeysFourthRow[4] = new JButton("C");
            buttonKeysFourthRow[5] = new JButton("V");
            buttonKeysFourthRow[6] = new JButton("B");
            buttonKeysFourthRow[7] = new JButton("N");
            buttonKeysFourthRow[8] = new JButton("M");
            buttonKeysFourthRow[9] = new JButton(",\n;");
            buttonKeysFourthRow[10] = new JButton(".\n:");
            buttonKeysFourthRow[11] = new JButton("^");
            break;
        case 5:
            buttonKeysFifthRow[0] = new JButton("                             ");
            buttonKeysFifthRow[1] = new JButton("<");
            buttonKeysFifthRow[2] = new JButton("v");
            buttonKeysFifthRow[3] = new JButton(">");
            break;
        } // end switch
    } // end method initializeKeys

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TypingTutor();
            }
        });
    }

} // end class TypingTutor
person Gilbert Le Blanc    schedule 08.01.2015
comment
Это не соответствует макету, который пытается достичь вопрос. - person VGR; 09.01.2015
comment
Центрирование JLabels было решением моей проблемы, большое спасибо. - person Dazt; 10.01.2015