如何在多个jpanel中使用变量?

时间:2012-07-23 20:38:27

标签: java swing jpanel

我有一个带有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);
    }
}

3 个答案:

答案 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(事件!)。控制器,服务等

这对你也有帮助:

Up-to-date Swing MVC example + Question

答案 2 :(得分:2)

你做不到。正如您所注意到的,控件一次只能附加到一个窗口,如果您尝试将其附加到另一个窗口,它将从第一个窗口中删除。

建议:

panel2.add(text.clone()); // clone the existing label
panel2.add(new JLabel("some text")); // make a new label from scratch