Боюсь, вы ошиблись.
Используйте ответ Стюарта и установите нулевой менеджер раскладки. Это позволяет вам устанавливать положение всех компонентов, вызывая setBounds ().
Затем добавьте слушателя в окно, которое вызывается при каждом изменении размера окна, и пересчитайте позиции и вызовите setBounds ().
Это все может быть автоматизировано, если вы реализуете свой код позиционирования как менеджер раскладки. (В конце концов, располагая компоненты в соответствии с изменением размера == управлением макетом, поверьте или нет, вы разрабатываете менеджер макетов, это так просто!)
public class MyLayout implements LayoutManager,LayoutManager2 {
@Override
public void addLayoutComponent(Component comp, Object constraints) {
// TODO Auto-generated method stub
}
@Override
public Dimension maximumLayoutSize(Container target) {
// TODO Auto-generated method stub
return null;
}
@Override
public float getLayoutAlignmentX(Container target) {
// TODO Auto-generated method stub
return 0;
}
@Override
public float getLayoutAlignmentY(Container target) {
// TODO Auto-generated method stub
return 0;
}
@Override
public void invalidateLayout(Container target) {
// TODO Auto-generated method stub
}
@Override
public void addLayoutComponent(String name, Component comp) {
// TODO Auto-generated method stub
}
@Override
public void removeLayoutComponent(Component comp) {
// TODO Auto-generated method stub
}
@Override
public Dimension preferredLayoutSize(Container parent) {
// TODO Auto-generated method stub
return null;
}
@Override
public Dimension minimumLayoutSize(Container parent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void layoutContainer(Container parent) {
// Now call setBounds of your components here
}
}
В методе layoutContainer вы можете вызывать setBounds всех компонентов. Этот метод вызывается при первоначальном размещении окна, а также каждый раз, когда происходит изменение размера.
Тогда, когда вы, например, положить вещи в окно или в JPanel, просто setLayoutManager (новый MyLayoutManager ()), и вы золотой.
Однако очень грубый вопрос все еще остается. Ваш менеджер компоновки - это отдельный класс, но он все же должен иметь доступ к компонентам, которые вы создали в другом месте кода вашего окна. Решение проблемы грубой силы состоит в том, чтобы просто получить ссылку на все компоненты в конструкторе, например ::
class MyWindow extends JFrame {
public MyWindow() {
JLabel label=new JLabel("Hello");
JButton button=new JButton("Ok");
setLayoutManager(new MyLayoutManager(label,button)); // PASS THEM
add(label);
add(button);
pack();
setVisible(true);
}
}
Конечно, это наивный подход, но может сработать. Правильный способ решения этой проблемы заключается в реализации addLayoutComponent в вашем менеджере компоновки, который вызывается всякий раз, когда вы добавляете что-либо в JFrame (например, при вызове add (label)). Таким образом, менеджер макета узнает о компонентах в макете.