Макет Java Swing JFrame

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

Если я пишу код кнопки после текстового поля, то отображается только кнопка.

Есть идеи, почему?

    JFrame mainframe=new JFrame();
    mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    mainframe.setBounds(0,0,200,200);
    JButton jb=new JButton();
    jb.setText("Leech");
    mainframe.add(jb);
    JTextField link=new JTextField(50);
    mainframe.add(link);
    mainframe.pack();
    mainframe.setVisible(true);

person DanMatlin    schedule 28.12.2011    source источник
comment
В классе javadoc четко указано, что вы также можете вызвать add, что добавит его на панель содержимого. По крайней мере, в более поздних версиях Java документация 1.3, на которую вы ссылаетесь   -  person Robin    schedule 29.12.2011


Ответы (6)


Добавьте свои компоненты в JPanel, а затем добавьте эту панель в ContentPane JFrame.

JFrame window = new JFrame();
JPanel mainframe = new JPanel();

window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(0,0,200,200);

JButton jb = new JButton();
jb.setText("Leech");

mainframe.add(jb);

JTextField link = new JTextField(50);
mainframe.add(link);

window.getContentPane().add(mainframe);
window.pack();
window.setVisible(true);
person Ibrahim    schedule 28.12.2011
comment
что в основном то же самое, что и установка FlowLayout как LayoutManager на JFrame, так как это макет по умолчанию из JPanel - person Robin; 29.12.2011
comment
Не могу поверить, что это принятый ответ. Ответ Робина ниже является правильным ответом. Просто нужно понять, что такое менеджер компоновки по умолчанию для JFrame и позиция по умолчанию, в которую что-то добавляется в BorderLayout, если она не указана. - person Michael; 26.04.2017
comment
@ Майкл, в чем смысл твоего комментария? Считаете ли вы этот ответ неправильным или вам не нравится, как он закодирован таким образом? - person Ibrahim; 03.05.2017
comment
@ Ибрагим, вопрос ОП, был «Есть идеи, почему?», вы не объяснили, почему его код не работал, ответ Робина объясняет, почему - person Michael; 04.05.2017
comment
@ Майкл, когда я спрашиваю, почему что-то не работает, я имею в виду, может ли кто-нибудь заставить это работать для меня. Но я так думаю, и я предполагаю, что он хочет, чтобы и кнопка, и текстовое поле отображались в окне. Он принял это как ответ, потому что нашел то, что искал. Для других людей, которые действительно хотят знать, почему они проголосовали за ответ Робина, и вы можете видеть, что он получил больше голосов, поэтому вы можете прочитать ответ с наибольшим количеством голосов, что я и делаю в stackoverflow. - person Ibrahim; 04.05.2017

Макет по умолчанию для JFrame — это BorderLayout. Вызов метода add для Container с такой компоновкой эквивалентен вызову add(..., BorderLayout.CENTER). Каждое из местоположений BorderLayout может содержать только один элемент. Следовательно, делая два вызова

mainframe.add(jb);
mainframe.add(link);

приводит к CENTER, содержащему последний добавленный компонент. Если вы хотите избежать этого, вы можете либо добавить его в другое место, либо использовать другой менеджер компоновки (например, FlowLayout), вызвав JFrame#setLayout

person Robin    schedule 28.12.2011
comment
Так какой смысл в панелях, если вы можете просто сделать это в кадре? - person NoName; 18.07.2019

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

Здесь вы можете найти несколько руководств по менеджерам компоновки.

В основном в Swing LayoutManager отвечает за размещение дочерних компонентов (устанавливая их положение и размер), поэтому каждый компонент-контейнер, который вы используете внутри своего приложения, должен быть настроен с помощью соответствующего LayoutManager.

person Heisenbug    schedule 28.12.2011
comment
Ссылка на LayoutManager теперь мертва. Пожалуйста исправьте. - person Ungeheuer; 04.01.2016

Диспетчер компоновки JFrame по умолчанию — BorderLayout. Если вам нужен автоматический макет, вы можете использовать FlowLayout:

mainframe.setLayout(new FlowLayout());

Если вы хотите указать координаты методом setBounds(), вы должны отменить настройку менеджера компоновки на JFrame:

mainframe.setLayout(null);
jb.setBounds(10,10,100,50);
link.setBounds(10,70,180,100);
person guest    schedule 27.09.2014
comment
Вы никогда не должны рекомендовать устанавливать для макета значение null, это просто неправильно. - person Michael; 04.05.2017

если вы видите документацию BorderLayout mainframe.add(jb); равно mainframe.add(jb,BorderLayout.CENTER); mainframe.add(ссылка); равно mainframe.add(jb,BorderLayout.CENTER);

так что он просто показывает последний

person John Dadi Leop    schedule 05.06.2017

Вы также можете использовать что-то вроде Flow Layout, который является макетом по умолчанию, используемым JPanel. Он используется для размещения компонентов в линию или ряд. Например, слева направо или справа налево:

введите здесь описание изображения

Компоновка Flow выстраивает компоненты в линию, и если места не осталось, все оставшиеся компоненты переходят на следующую строку. Свойство Align определяет выравнивание компонентов по левому краю, правому краю, центру и т. д.

Чтобы использовать его, вам нужно будет установить макет JFrame с помощью JFrame.setLayout(layout) и передать макет потока в качестве параметра.

В следующем примере показаны компоненты, расположенные в виде потока:

package example.com;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;

public class FlowLayoutExample {

    FlowLayoutExample(){
        JFrame frame = new JFrame("Flow Layout");
        JButton button, button1, button2, button3, button4;
        button = new JButton("button 1");
        button1 = new JButton("button 2");
        button2 = new JButton("button 3");
        button3 = new JButton("button 4");
        button4 = new JButton("button 5");
        frame.add(button);
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
        frame.add(button4);
        frame.setLayout(new FlowLayout());
        frame.setSize(300,300);  
        frame.setVisible(true);  

    }
    public static void main(String[] args) {
        new FlowLayoutExample();
    }
}

Посетите узнать больше о макетах JFrame.

person Johnny    schedule 04.05.2019