Создание компонента занимает только определенную долю пространства (например, 2/3 или 9/10) - PullRequest
1 голос
/ 06 августа 2011

Использование макетов для меня приводит к такому большому разочарованию, что я в конечном итоге использую абсолютный макет, а затем масштабирую компоненты вручную.

Допустим, у меня есть TextArea, и я хочу, чтобы он занимал 2/3экран.Что я действительно хотел бы, так это иметь GridLayout с 3 строками и заставлять TextArea принимать сразу две из этих строк.

Так, например:

  • Строка 1 (Занятоfirst textArea)
  • Строка 2 (Занято той же текстовой областью)
  • Строка 3 (Занято кнопками)

Вот изображение с использованием макета Gridbag (изменено из Java-учебник л).Я бы хотел, чтобы область, выделенная зеленым цветом, была занята одним компонентом.

GridBagLayout

Это просто способ выразить себя, я уверен, что есть и другие способы (или макеты) для этого.Однако обратите внимание, что я также хотел бы сделать это с другими определенными шкалами, такими как 9/10.

Это сэкономило бы так много времени.Спасибо!

Ответы [ 4 ]

4 голосов
/ 06 августа 2011

В общем, вы не должны играть с абсолютными процентами, особенно на отдельных композитах. Вы должны позволить компоненту отображаться в его предпочтительном размере. Так что твой пример действительно не имеет никакого смысла. Когда у вас есть форма с текстовой областью и кнопками. Тогда изменения в размере должны влиять на текстовую область, а не на кнопки. Затем вы добавляете полосу прокрутки в текстовую область, чтобы полоса прокрутки появлялась или исчезала по мере необходимости.

Однако, если по какой-то причине вам нужно использовать абсолютные проценты на уровне панели, вы можете использовать код, подобный следующему:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GridBagSSCCE extends JPanel
{
    JPanel red;
    JPanel green;

    public GridBagSSCCE()
    {
        setLayout( new GridBagLayout() );
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.VERTICAL;

        red = new JPanel();
        red.setBackground( Color.RED );
        red.setPreferredSize( new Dimension(300, 10) );
        gbc.weighty = 0.1;
        add(red, gbc);

        green = new JPanel();
        green.setBackground( Color.GREEN );
        green.setPreferredSize( new Dimension(300, 90) );
        gbc.gridy = 1;
        gbc.weighty = 0.9;
        add(green, gbc);

        JPanel buttons = new JPanel();
        buttons.add( new JButton("Ok") );
        buttons.add( new JButton("Cancel") );
        buttons.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
        gbc.gridy = 2;
        gbc.weighty = 0.0;
        gbc.anchor = GridBagConstraints.LINE_END;
        add(buttons, gbc);

        addComponentListener( new ComponentAdapter()
        {
            public void componentResized(ComponentEvent e)
            {
                System.out.println(red.getSize() + " : " + green.getSize());
            }
        });
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("GridBagSSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new GridBagSSCCE() );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
    }

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

Ключ в приведенном выше коде - начать с предпочтительного размера при желаемом соотношении (10/90), а также установить весовые коэффициенты компонентов в том же соотношении.

Если вы хотите, вы также можете проверить Относительный макет , который был написан специально для этой цели.

Edit:

GridBagLayout не отображает компоненты в процентах. То, что у вас есть две строки, не означает, что каждая строка составляет 50%. Высота каждой строки зависит от высоты каждого компонента, добавляемого в каждую строку.

Сначала вы решаете, какой объем данных будет отображаться в текстовой области. Для двух строк вы бы использовали что-то вроде:

JTextArea textArea = new JTextArea(2, 40);
JScrollPane scrollPane = new JScrollPane( textArea );

Затем вы создаете панель с кнопками.

Может получиться, что текстовая область с 2 строками примерно такого же размера, как панель с кнопками, потому что панель добавляет вертикальный разрыв над и под компонентом, а кнопка имеет относительно большую границу, но это просто совпадение , Но вы не должны заставлять текстовую область быть больше половины. Просто позвольте менеджеру раскладки и методу pack () выполнить свою работу.

Теперь вам нужно решить, что произойдет, когда размер кадра увеличится, так как это определит менеджер компоновки родительского контейнера. В этом случае я бы, вероятно, использовал BorderLayout, поэтому я бы использовал такой код:

frame.add(scrollPane, BorderLayout.CENTER);
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.pack();

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

3 голосов
/ 06 августа 2011
import java.awt.*;
import javax.swing.*;

public class CopyTextNorthPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    private JLabel hidelLabel;
    private JLabel firstLabel;
    private JTextField firstText;

    public CopyTextNorthPanel() {

        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
        for (int k = 0; k < 50; k++) {
            hidelLabel = new JLabel("     ");
            hidelLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 0.5;
            gbc.weighty = 0.5;
            gbc.gridx = k;
            gbc.gridy = 0;
            add(hidelLabel, gbc);
        }
        for (int k = 0; k < 5; k++) {
            firstLabel = new JLabel("Testing Label : ", SwingConstants.RIGHT);
            firstLabel.setFont(new Font("Serif", Font.BOLD, 20));
            firstLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(0, 0, 5, 0);
            gbc.gridx = 0;
            gbc.gridwidth = 8;
            gbc.gridy = k + 1;
            add(firstLabel, gbc);
        }
        for (int k = 0; k < 5; k++) {
            firstText = new JTextField("Testing TextField");
            firstText.setFont(new Font("Serif", Font.BOLD, 20));
            firstText.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(0, 0, 5, 0);
            gbc.gridx = 9;
            gbc.gridwidth = k + 8;
            gbc.gridy = k + 1;
            add(firstText, gbc);
        }
        for (int k = 0; k < 5; k++) {
            firstLabel = new JLabel("Testing Label : ", SwingConstants.RIGHT);
            firstLabel.setFont(new Font("Serif", Font.BOLD, 20));
            firstLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(0, 0, 5, 0);
            gbc.gridx = 20 + k;
            gbc.gridwidth = 8;
            gbc.gridy = k + 1;
            add(firstLabel, gbc);
        }
        for (int k = 0; k < 5; k++) {
            firstText = new JTextField("Testing TextField");
            firstText.setFont(new Font("Serif", Font.BOLD, 20));
            firstText.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(0, 0, 5, 0);
            gbc.gridx = 29 + k;
            gbc.gridwidth = 21 - k;
            gbc.gridy = k + 1;
            add(firstText, gbc);
        }
    }
}
2 голосов
/ 06 августа 2011

Я не думаю, что GridBagLayout будет работать в этой конкретной ситуации, так как вы не имеете столько контроля над относительной шириной, сколько вам нужно.Вместо этого я предлагаю вам ознакомиться с MiGLayout , макетом, который, хотя и не является частью ядра Java, является бесплатным для загрузки, но чрезвычайно гибким и мощным и доступен для Swing и некоторых других библиотек графического интерфейса.

1 голос
/ 06 августа 2011

Learn GridBagLayout. Серьезно, как только вы изучите это, вы сможете быстро сделать все, что вам нужно. Вам также может пригодиться дизайнер GUI. Для свинга мне лично нравится тот, что в netbeans.

Макет разочаровывает, пока вы не научитесь его использовать. Помните, что вы создаете приложение для своих пользователей. Они будут разочарованы каждый раз, когда захотят изменить размер окна. Вы этого не хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...