我有一个带有var的框架,我将var添加到JPanel,如果我想将相同的var添加到另一个JPanel,它会从第一个JPanel中消失。我想对我的问题进行合理的解释,谢谢! 我想将JLabel存储在我的两个jpanel中。
public class Gui {
JPanel panel1, panel2;
JLabel text = new JLabel("some text");
JFrame frame = new JFrame();
public Gui {
panel1 = new JPanel();
panel1.setLayout(null);
panel1.add(text);
panel1.getComponent(0).setBounds(50,50,50,50);
panel1.setBorder(BorderFactory.createLineBorder(Color.black));
panel1.setBounds(x,y,w,h);
// it`s working, the labels it`s visible
panel2 = new JPanel();
panel2.setLayout(null);
panel2.add(text);
panel2.getComponent(0).setBounds(100,100,50,50);
panel2.setBorder(BorderFactory.createLineBorder(Color.black));
panel2.setBounds(x,y,w,h);
//it`s not working, the label ins`t visible ...
frame.add(panel1);
frame.add(panel2);
}
}
答案 0 :(得分:3)
免责声明:我正在编辑我的回答以回应OP的评论。但是,我仍然不完全确定问题的一些细节。随着更多的澄清,我很乐意编辑我的答案。
答案:一种可能的解决方案是创建您正在使用的Swing组件的子类。例如,
public class MyPanel extends JPanel {
private JLabel label = new JLabel("some text");
public MyPanel() {
this.add(label);
}
}
现在您可以创建MyPanel
的多个实例,每个实例都有自己的JLabel。然后,您可以将这些面板添加到您的框架中。
已添加:根据评论中提供的其他信息,我会更进一步,创建一个自定义JFrame类:
public class MyFrame extends JFrame {
private MyPanel panel = new MyPanel();
public MyFrame() {
this.add(panel);
}
}
现在您可以创建MyFrame
的多个实例。如果您想更进一步,可以将参数添加到这两个自定义类的构造函数中,以将JLabel
文本设置为每个实例MyFrame
中的不同值。我会将细节作为练习留给读者。 (当然,请问你是否卡住了。)
答案 1 :(得分:3)
正如在其他帖子中讨论过的那样。所有Swing UI组件(包括JLabel)只能有一个父组件(即JPanel)。如果将其添加到另一个面板,它将从前一个父项中删除它。这种行为有很好的理由。例如,JPanel 1可能不使用与JPanel 2相同的布局,因此标签必须支持每个JPanel中的两个不同的放置。使用对象作为组件的重点是在该对象内提供数据的封装,如(字体,父级内的位置,宽度,高度等)。如果你想要两个视觉元素,只需创建另一个元素。现在,这会产生一个问题“如何在所有这些控件之间同步数据?”那基本上是在抓你如何为你的程序构建一个合适的Swing架构?
您不想做的是使用Swing组件模型(即Jabel,JTextField等)作为您的数据模型。在阅读了你的问题和代码后,我相信你正在做的事情。你可能没有意识到这一点。 UI组件应仅用于显示。它们反映了数据模型中的内容。因此,您需要创建一个不涉及Swing的模型。它应该模拟您的问题,无论其显示方式如何。这意味着你不应该假设它总是Swing或web等。
这有非常实际的原因。比如说你想在一年内重新设计你的用户界面。如果将视图组件和数据模型组合在一起,则必须完全重新开始。即使你没有切换技术。假设您正在从JList切换到JTable或JTreeTable。如果不从模型中分割视图,只需简单地更改屏幕上的组件类型就可能是绝对的噩梦。此外,View会显示事物,但模型可能需要未向用户显示但与所显示内容相关的信息。例如,数据库中行的ID。如果你把视图和数据模型放在一起,你必须玩一些小的黑客来以奇怪的方式存储这些不可见的信息。让其他人难以理解的事情。
如果你不知道我的意思,你将在6个月内完成你的第一次重大重新设计,或者你现在可以省去一些痛苦并试着理解我现在的意思。只需简单的POJO即可。然后与Swing组件共享这些POJO。例如:
MySpecialPanel panel1 = new MySpecialPanel();
MyOtherSPecialPanel panel2 = new MyOtherSpecialPanel();
frame.add( panel1 );
frame.add( panel2 );
...a little while later...
MySpecialPOJO specialPOJO = ...some call to a service...;
panel1.setSpecialPOJO( specialPOJO );
panel2.setSpecialPOJO( specialPOJO );
请注意,我创建了两个名为MySpecialPanel和MyOtherSpecialPanel的JPanel子类。在那里,他们创建了包含在其中的组件。然后公开一个采用MySpecialPOJO类型的数据模型对象的setter方法。在这些方法中,我们可能会看到如下内容:
public void setSpecialPOJO( MySpecialPOJO specialPOJO ) {
this.model = specialPOJO;
textField1.setText( specialPOJO.getName() );
textField2.setText( specialPOJO.getDescription() );
radioButtonGroup.setSelected( specialPOJO.getGender() );
....
}
现在,您可以获取模型对象,并更新构成该视图的相对UI组件。请注意,它不关心任何其他外部依赖项(即从中获取对象的位置)。它只是更新它拥有的控件以反映POJO所携带的内容。现在,如果您遵循这些简单的规则,它可以轻松实例化您的特殊面板。是否只需要一个实例或多个实例。此外,如果您需要在程序中移动面板,那么如果您将依赖关系减少到仅仅是POJO,则很容易实现。还有很多东西,但是现在这将让你开始。您仍然需要弄清楚如何从UI中获取数据并返回到您的POJO(事件!)。控制器,服务等
这对你也有帮助:
答案 2 :(得分:2)
你做不到。正如您所注意到的,控件一次只能附加到一个窗口,如果您尝试将其附加到另一个窗口,它将从第一个窗口中删除。
建议:
panel2.add(text.clone()); // clone the existing label
panel2.add(new JLabel("some text")); // make a new label from scratch