Каково отношение между ContentPane и JPanel?

Я нашел один пример, в котором кнопки добавляются к панелям (экземпляры JPanel) затем панели добавляются к контейнеры (экземпляры, сгенерированные getContentPane()) и затем контейнеры, конструкцией, включенной в JFrame (окна).

Я попробовал две вещи:

  1. Я избавился от контейнеров. Более подробно я добавил кнопки к панели (экземпляр JPanel) и затем я добавил панель к окнам (экземпляр JFrame). Это хорошо работало.

  2. Я избавился от панелей. Более подробно я добавил кнопки непосредственно к контейнеру, и затем я добавил контейнер к окну (экземпляр JFrame).

Так, я не понимаю две вещи.

  1. Почему у нас есть два конкурирующих механизма, чтобы сделать то же самое?

  2. Что является причиной использовать контейнеры в сочетании с панелями (JPanel)? (Например, что, поскольку мы включаем кнопки в JPanels и затем мы включаем JPanels в Контейнеры). Мы можем включать JPanel в JPanel? Мы можем включать контейнер в контейнер?

ДОБАВЛЕННЫЙ:

Возможно, сущность моего вопроса может быть помещена в одну строку кода:

frame.getContentPane().add(panel);

Зачем мы помещаем getContentPane() промежуточный? Я попробовал просто frame.add(panel); и это хорошо работает.

ДОБАВЛЕННЫЙ 2:

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

import java.awt.*;
import javax.swing.*;
public class HelloWorldSwing {
    public static void main(String[] args) {
        JFrame frame = new JFrame("HelloWorldSwing");
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());        
        panel.add(new JButton("W"), BorderLayout.NORTH);
        panel.add(new JButton("E"), BorderLayout.SOUTH);
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

И в этом примере я использую только Область Содержания:

import java.awt.*;
import javax.swing.*;
public class HelloWorldSwing {
    public static void main(String[] args) {
    JFrame frame = new JFrame("HelloWorldSwing");
    Container pane = frame.getContentPane();
    pane.setLayout(new BorderLayout()); 
    pane.add(new JButton("W"), BorderLayout.NORTH);
    pane.add(new JButton("E"), BorderLayout.SOUTH);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
    }
}

Оба хорошо работают! Я просто хочу знать, (более ли между этими двумя способами сделать вещи каждый лучше безопасен).

33
задан Lucio 26 April 2014 в 21:32
поделиться

5 ответов

Это не два конкурирующих механизма - JPanel - это Контейнер (просто посмотрите на иерархию классов на вверху JPanel javadocs ). JFrame.getContentPane () просто возвращает Контейнер для размещения Component s, которые вы хотите отобразить в JFrame . Внутри он использует JPanel (по умолчанию - вы можете изменить это, вызвав setContentPane () ). Что касается того, почему он возвращает Контейнер вместо ] JPanel - это потому, что вы должны программировать интерфейс, а не реализацию - на этом уровне все, о чем вам нужно заботиться, это то, что вы можете добавить Component s в что-то - и хотя Контейнер является скорее классом, чем интерфейсом, он предоставляет интерфейс, необходимый именно для этого.

Что касается того, почему оба JFrame.add () и JFrame.getContentPane (). Add () делают одно и то же - JFrame.add () переопределяется для вызова JFrame.getContentPane (). add () . Так было не всегда - до JDK 1.5 вам всегда приходилось указывать JFrame.getContentPane (). Add () явно и JFrame.add () сгенерировал исключение RuntimeException , если вы его вызвали, но из-за множества жалоб это было изменено в JDK 1.5, чтобы сделать то, что вы ожидаете.

31
ответ дан 27 November 2019 в 18:37
поделиться

Хороший вопрос. Мне было полезно понять, что «Swing предоставляет три обычно полезные классы контейнеров верхнего уровня: JFrame , JDialog и JApplet . ... Для удобства ce, метод add и его варианты, remove и setLayout были переопределены для пересылки в contentPane по мере необходимости ». - Использование контейнеров верхнего уровня

3
ответ дан 27 November 2019 в 18:37
поделиться

Я полагаю, что причина в том, что Swing был создан на основе AWT, а Container - это объект AWT верхнего уровня. Однако это не самый лучший выбор дизайна, поскольку вы, как правило, не хотите смешивать объекты AWT (тяжелые) с объектами Swing (легкими).

Я думаю, что лучший способ справиться с этим - всегда приводить contentPane к JPanel.

JPanel contentPanel = (JPanel)aFrame.getContentPane();
1
ответ дан 27 November 2019 в 18:37
поделиться

В последней версии API doc написано, что достаточно JFrame.add () (nowerdays).

Вы можете сравнить со старыми версиями Java здесь .

1
ответ дан 27 November 2019 в 18:37
поделиться

интересно: jframe.setBackground (color) делает не работает для меня, но jframe.getContentPane (). setBackground (color) работает.

1
ответ дан 27 November 2019 в 18:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: