Когда второй компонент добавлен к тому же (в данном случае CENTER) ограничению BorderLayout, эта реализация Java покажет последний добавленный компонент.
Не совсем верно.
BorderLayout
будет только reset the bounds
(т.е. размер и местоположение) последнего компонента, добавленного в определенное место ограничения. Это отличается от других менеджеров компоновки тем, что они сбросят границы всех компонентов в контейнере.
В примере кода красная панель была «активной» панелью во время проверки кадра с использованием метода pack(), и поэтому была установлена только его граница, и поэтому только она была нарисована.
Для демонстрации этого процесса запустить пример ниже, используя следующие шаги:
- Нажмите на кнопку «Добавить панель в Центре», ничего не кажется произойдет, даже если синяя панель была добавлена в центре ,
- Наведите указатель мыши на красную панель, и появятся кнопки, потому что логика опрокидывания мыши приведет к перекрашиванию кнопок.
- Теперь увеличьте ширину рамки, и синяя панель появится под красной панелью.
Код:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class DisappearingPanelInFrame {
DisappearingPanelInFrame()
{
JButton button = new JButton ("Add Panel In Center");
button.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
JPanel blue = new JPanel();
blue.setBackground(Color.BLUE);
blue.add(new JButton("Button 1"));
blue.add(new JButton("Button 2"));
Component c = (Component)e.getSource();
Window window = SwingUtilities.windowForComponent(c);
window.add(blue);
window.revalidate();
window.repaint();
}
});
JFrame f = new JFrame(this.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.add(new ColoredPanel(Color.GREEN));
//f.pack();
f.add(new ColoredPanel(Color.RED));
f.add(button, BorderLayout.SOUTH);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
new DisappearingPanelInFrame();
}
};
SwingUtilities.invokeLater(r);
}
}
class ColoredPanel extends JPanel {
ColoredPanel(Color color) {
setBackground(color);
setBorder(new EmptyBorder(20, 150, 20, 150));
}
}
Когда синяя панель добавляется к BorderLayout и когда revalidate()
вызываются за пределы синих панелей установлена.
Однако из-за того, что Swing рисует ZOrder, сначала рисуется синяя панель, а затем красная панель окрашивается поверх синей панели. Зеленая панель по-прежнему имеет размер (0, 0), поскольку она никогда не была «активной» панелью в BorderLayout.CENTER
, когда кадр был первоначально проверен с помощью метода pack().
При изменении размера рамки синяя панель, являющаяся «активной» панелью в BorderLayout.CENTER
, имеет свои границы, поэтому теперь она заполняет дополнительное пространство в кадре.
Теперь для другого теста:
pack()
кадр после добавления зеленой панели к раме.
- запустить код и увеличить ширину рамы, а красный и зеленый появится рамка
- затем нажмите кнопку и увеличить ширину, и теперь все 3 панели появится
Нижняя линия все то же:
Не пытайтесь добавить несколько панелей к тому же ограничению BorderLayout. Если вы это сделаете, убедитесь, что вы удалили предыдущую панель или у вас есть потенциал для неожиданных результатов.
Определенно [автоответчик-FAQ] (http://meta.stackoverflow.com/q/17463/163188); для использования «границы» для получения определенного начального размера; поскольку вы расширяете 'JPanel', также учитывайте переопределение [' getPreferredSize() '] (http://stackoverflow.com/q/7229226/230513). – trashgod
@trashgod Да. Я решил переопределить 'getPreferredSize()' вместо того, чтобы устанавливать границу (я также считал, что просто устанавливаю размер для самого кадра!). Я был между двумя разными подходами. 1) Используйте лучшие практики во всех отношениях. 2) Сделайте весь образец кода в едином блоке кода без вертикальной полосы прокрутки. - В этом случае последний выиграл (в основном). ;) –