Копирование содержимого JPanel в другую JPanel без удаления содержимого исходной JPanel

#java #swing #jpanel

#java #swing #jpanel

Вопрос:

Я новичок в Java swing coding. Я пытаюсь скопировать содержимое JPanel в новую JPanel, которая использует содержимое исходной JPanel для отображения. Кроме того, исходное содержимое JPanel изменяется по мере изменения записей. Я попробовал следующий код, но он совершенно бесполезен.

 public void addPanel(JPanel jp)
{
    JPanel jp1=new JPanel();
    int count=jp.getComponentCount()-1;
    for(;i>=0;i--)
    {
         jp1.addComponent(jp.getComponent(i);
    }
    //after this I am setting bounds of jp1.
this.add(jp1);
}
 

Это не сработает, если я хочу внести несколько JPanels в качестве исходных изменений JPanel. Он перезаписывает содержимое нового ‘jp’ поверх ‘jp1’, если используется несколько раз, скажем, если используется в цикле for.
Я не хочу удалять компоненты исходной JPanel. Как я могу это сделать?

Комментарии:

1. «Я пытаюсь скопировать содержимое JPanel в новую JPanel, которая использует содержимое исходной JPanel для отображения.» .. Почему? Обратите внимание, что компонент может быть добавлен только к одному родительскому элементу (и его можно увидеть). Вот почему он не работает.

2. И что именно вернет getParent() метод этих компонентов? Или getRootPane() ? И какой из родителей установит ширину и высоту компонента (которые, конечно, хранятся в нем)? J-компоненты никогда не предназначались для совместного использования, если вы хотите скопировать — делайте копии, не делитесь.

3. Не дублируйте компонент просмотра , например JComponent ; обновите модель компонента, например label.setText() .

Ответ №1:

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

Вы можете сделать это как программу, создав новые экземпляры исходного класса и затем вызвав установщики со значениями получателей… Но, честно говоря, это способ, подверженный ошибкам, и для этого вам потребуется отражение, которое вы не должны использовать, если это действительно необходимо.

Что вы можете сделать, так это переопределить стандартные классы Java, которые вы используете (например, JLabel), и в вашем переопределенном классе вы реализуете Cloneable , где вы устанавливаете нужные вам параметры (текст, границы, что угодно), а затем вызываете свою функцию следующим образом:

 public void addPanel(JPanel jp)
{
    JPanel jp1=new JPanel();
    int i=jp.getComponentCount()-1;
    for(;i>=0;i--)
    {
         jp1.addComponent(
              ((Component) // this casts the clone back to component. This is maybe superfluous.
               ((Cloneable)jp.getComponent(i) // You have to ensure that all components that are returned are in fact instances of Cloneable.
               ).clone()
              ));
    }
    //after this I am setting bounds of jp1.
    this.add(jp1);
}
 

Если вы пойдете по этому пути, обязательно ознакомьтесь с документацией Cloneable .

Комментарии:

1. Спасибо u Angelo за решение! Поскольку предполагается, что для любого компонента swing должен быть только один родительский элемент, я принял другой подход к решению этой проблемы. Я попробовал пример приложения, используя ваш код, и это сработало!

2. @mapp_301092 Спасибо. Если этот ответ помог вам, пожалуйста, отметьте «принять» слева или, что еще лучше, предоставьте свой собственный ответ с подробным описанием того, как вы решили проблему в конце, чтобы он служил будущим читателям.

Ответ №2:

Вот метод решения следующей проблемы без кодирования, просто используя проектные представления JPanels / JFrames.

Вы можете перейти в навигатор в режиме конструктора, выбрать все компоненты JPanel и скопировать их, набрав ctrl a и ctrl c. Затем создайте еще одну JPanel и в режиме конструктора просто вставьте их с помощью ctrl v.

Результат: вы получаете все компоненты одинакового размера, размеров и позиций с одинаковыми свойствами и значениями. После того, как вы сделаете это, вы можете легко изменить все, что захотите, используя свойства форм GUI.