Как расположить компонент относительно другого компонента? - PullRequest
0 голосов
/ 15 января 2012

Я хочу иметь следующий макет:

(т.е. jbutton и jlabel размещаются на jpanel, jbutton центрируется, а jlabel идет сразу после него. Макет должен иметь возможность изменять размер. Редактировать: Размер jbutton и jlabel постоянен при изменении размера.)

Я думал о следующем:

  1. Используйте соответствующий менеджер раскладки. Я не знаю ни одного. Я могу добавить jbutton и jlabel к другой jpanel и добавить эту новую jpanel в центр большой jpanel, но в этом случае jbutton не будет отцентрирован.

    Редактировать: Я пытался использовать это предложение: (предложение было отредактировано и код там сейчас правильный)

    public class MainFrame extends JFrame {
        public static void main(String[] args) {
            new MainFrame();
        }
    
    <pre><code>public MainFrame() {
        setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1;
        add(new JPanel(), c);
        c.gridx = 1;
        c.weightx = 0;
        c.anchor = GridBagConstraints.CENTER;
        add(new JButton("Button"), c);
        c.gridx = 2;
        c.weightx = 1;
        c.anchor = GridBagConstraints.WEST;
        add(new JLabel("Label"), c);
        pack();
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    </code>
    } }

    Но он производит следующий вывод, где кнопка не центрирована:

  2. Добавьте кнопку и метку в панель. Добавьте ComponentListener к jpanel и переопределите componentResized там. Переопределенный метод будет выглядеть так:

    public void componentResized(ComponentEvent e) {
        int x = button.getX() + button.getWidth() + 3;
        int y = button.getY();
        label.setLocation(new Point(x, y));
    }  
    

    Позиция JButton будет выбрана при автоматическом изменении размера менеджером по расположению и позицией jlabel этим методом. Но componentResized будет вызываться только после завершения изменения размера. Таким образом, в процессе изменения размера позиция jlabel будет определяться менеджером по расположению, что нежелательно.

  3. Добавьте jbutton на панель содержимого и jlabel на панель. Но у меня будет та же проблема с изменением размера, что и в предыдущем случае.

Как мне добиться этого макета?

Ответы [ 2 ]

1 голос
/ 15 января 2012

Используйте LayoutManager, который поддерживает ваши потребности, это путь. Продвинутые менеджеры позволяют определять группы (из столбцов / строк), размер которых всегда равен ширине / высоте. Если основные менеджеры не допускают таких семантических спецификаций, обратитесь к стороннему менеджеру, например любой из BigThree: MigLayout, FormLayout или DesignGridLayout. Время, потраченное на обучение, будет хорошо потрачено: -)

В MigLayout (мой личный любимый в настоящее время) противопоказанием является «sizegroup groupName» или «sg groupName» (где groupName может быть пустым, если есть только в группе), f.i.

    JButton button = new JButton("somesize");
    JLabel label = new JLabel("--outer--");
    MigLayout layout = new MigLayout("debug, wrap 3", 
           "[sizegroup, grow][center][sizegroup, grow]");
    JComponent comp = new JPanel(layout);
    // start adding component in second column 
    comp.add(button, "cell 1 0");
    comp.add(label);
    // add something spanning all column in second row for comparison
    comp.add(new JButton("somesize"), "span 3, center");
1 голос
/ 15 января 2012

Похоже, вы могли бы использовать макет мешка сетки с 3 столбцами. Первый и третий столбцы должны иметь одинаковый вес и, следовательно, иметь одинаковую ширину. Средняя колонна не имела бы веса, поэтому сидела бы посередине. Я бы попробовал это для вас, но я печатаю на iPhone! НТН

Смотрите комментарии, вот мое редактирование вашего примера кода:

public class MainFrame extends JFrame {
    public static void main(String[] args) {
        new MainFrame();
    }

    public MainFrame() {
        setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1;
        Component panel = new JPanel();
        panel.setBackground(Color.blue);
        add(panel, c);
        c.gridx = 1;
        c.weightx = 0;
        c.anchor = GridBagConstraints.CENTER;
        add(new JButton("Button"), c);
        c.gridx = 2;
        c.weightx = 1;
        c.anchor = GridBagConstraints.WEST;
        JLabel label = new JLabel("Label");
        add(label, c);

        panel.setPreferredSize(label.getPreferredSize());

        pack();
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
}
...