为新创建的每个JLabel创建鼠标侦听器

时间:2014-08-23 19:30:56

标签: java jlabel mouselistener

我正在建造一个家谱。该应用程序通过使用此代码按JLabel(图标为人物图片)创建一个JButton

JButton newPersonButton = new JButton("New Person");
newPersonButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {

        final Data data = NewPerson.createPerson(frame);
            if (data != null) {

                if (Val == "mother") {

                    JLabel lblHomer = new JLabel(data.names);
                    lblHomer.setIcon(new ImageIcon(data.fileID));
                    cooX = cooX + 20;
                    cooY = cooY - 20;
                    panel_1.add(lblHomer, "cell " + cooX + " " + cooY);
                    panel_1.revalidate();
                }

我需要点击现有的JLabel动态创建JLabel。我可以像创建第一个JLabel一样创建另一个JLabel,新JLabel使用创建的JLabel的坐标作为参考。不仅仅是一个,我需要{strong> ALL JLabel来生成这样的。当我点击它们然后它创建另一个。我知道如何通过点击它来创建一个新的JLabel lblHomer = new JLabel(data.names); lblHomer.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent arg0) { final Data data = NewPerson.createPerson(frame); if (data != null) { String Val = data.CBvalue; if (Val == "mother") { JLabel lblHomer = new JLabel(data.names); lblHomer.setIcon(new ImageIcon(data.fileID)); cooX = cooX + 20; cooY = cooY - 20; panel_1.add(lblHomer, "cell " + cooX + " " + cooY); panel_1.revalidate(); } } }

JLabel

但是,我无法无限地复制/粘贴相同的代码。我需要编写一个while循环或者其他东西来为我创建的每个public class Data { public final String names; public final String dateBirth; public final String bio; public final String fileID; public final String CBvalue; public Data(String names, String dateBirth, String bio, String fileID, String CBvalue) { this.CBvalue = CBvalue; this.names = names; this.dateBirth = dateBirth; this.bio = bio; this.fileID = fileID; } // getters } 创建鼠标监听器。我需要帮助。

整个代码:http://pastebin.com/zLx1zK9Z

编辑:Data.java:

{{1}}

2 个答案:

答案 0 :(得分:2)

首先...

 if (Val == "mother") {

不是你在Java中比较String的方式,而是你应该使用"mother".equals(Val)

接下来,你可以创建一个工厂方法来创建你的标签,甚至可能是一个实用程序类,它有几种不同的方法来创建你的标签,虽然我可能会考虑你到目前为止的构建器模式...

public static JLabel createPersonLabel(Data data, MouseListener listener) {
    JLabel lblHomer = new JLabel(data.names);
    lblHomer.setIcon(new ImageIcon(data.fileID));
    lblHomer.addMouseListener(listener);
}

然后我会创建一个自定义MouseListener来处理核心职能

public class DataMouseHandler extends MouseAdapter {
    public void mouseClicked(MouseEvent evt) {

        final Data data = NewPerson.createPerson(frame);
        if (data != null) {

            String Val = data.CBvalue;

            if ("mother".equals(Val)) {

                JLabel lblHomer = createPersonalLabel(data, this);

                cooX = cooX + 20;
                cooY = cooY - 20;
                panel_1.add(lblHomer, "cell " + cooX + " " + cooY);
                panel_1.revalidate(); 
            }
        }
    }
}

举个例子。您甚至可以为您可能需要的每种类型数据创建自定义MouseListener

<强>更新

有许多选项,例如,您可以在NewFamilyTree类中创建工厂样式方法,根据您的需要和数据类型创建和添加数据标签...

protected void createAndAddDataLabel(Data data) {

    JLabel lblHomer = new JLabel(data.names);
    lblHomer.setIcon(new ImageIcon(data.fileID));

    cooX = cooX + 20;
    cooY = cooY - 20;

    panel_1.add(lblHomer, "cell " + cooX + " " + cooY);
    panel_1.revalidate();

    if (!"mother".equals(data.CBvalue)) {
        lblHomer.addMouseListener(new DataMouseHandler());
    }

}

然后从你的按钮中调用它......

JButton newPersonButton = new JButton("New Person");
newPersonButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {

        final Data data = NewPerson.createPerson(frame);
        if (data != null) {

            createAndAddDataLabel(data);

        }
    }
});

而且,作为内部类,您可以定义DataMouseHandler ...

public class DataMouseHandler extends MouseAdapter {

    @Override
    public void mouseClicked(MouseEvent e) {

        final Data data = NewPerson.createPerson(frame);
        if (data != null) {
            if ("mother".equals(Val)) {
                createAndAddDataLabel(data);
            }
        }
    }
}

如果您需要将其作为外部类,则需要传递NewFamilyTree

的引用
public class DataMouseHandler extends MouseAdapter {

    private NewFamilyTree tree;

    public DataMouseHandler(NewFamilyTree tree) {
        this.tree = tree;
    }

    @Override
    public void mouseClicked(MouseEvent e) {

        final Data data = NewPerson.createPerson(frame);
        if (data != null) {
            if ("mother".equals(Val)) {
                tree.createAndAddDataLabel(data);
            }
        }
    }
}

<强>更新

现在,尽管如此,这是Model-view-controller方法最合适的典型例子。

你应该做的是以某种方式对家谱进行建模,这与家庭用户界线脱节,因此它只关注模型的要求,结构如何以及如何管理

当模型以某种方式发生变化时,该模型将提供事件通知的反馈。

从那里你可以围绕它包装一个UI,因此UI只负责渲染模型的输出。

控制器将从UI执行操作并相应地更新模型,这将依次触发从模型到UI的更新...

答案 1 :(得分:1)

如评论中所述,有几种方法可以做到这一点。我认为第一个建议可能是最好的,基于我/我们对你想做什么的了解很少。

public class ListenerLabel extends JLabel implements MouseListener
{
  public void mouseExited() {}
  public void mouseEntered() {}
  // etc.
  public void mouseClicked() {}
  {
    // here put the code you have for creating another person
    // 'this' refers to the label that was clicked on; you can get coordinates
    // and whatever you need from that.
  }
}

现在不是创建JLabel来保存你的人,而是创建ListenerLabels;它们将与您的用户界面进行交互,就像JLabels一样,但有额外的功能可以监听自己的点击次数。如果他们要包含特定于人的代码,那么他们的名字可能与人有关而不是倾听。 (&#39; PeopleLabels&#39;或其他)。

- 编辑 - 根据要求提供更多细节。

当我再次看到这个时,在我看来,你的NewPerson.createPerson()方法必须弹出一个对话框或某些东西来获取新人的信息。我将继续这个假设有效的例子,尽管我可能做的不同。

public void mouseClicked()
{
  final Data data = NewPerson.createPerson(frame);
  if (data != null)
  {
    if (data.CBvalue.equals("mother"))  // I would use a constant or enums here instead
    {
      ListenerLabel label = new ListenerLabel(data.names);
      label.setIcon(new ImageIcon(data.fileID));
      int xPosition = this.getX() + 20;
      int yPosition = this.getY() - 20;
      JPanel enclosingPanel = (JPanel)this.getParent();
      enclosingPanel.add(label, "cell " + cooX + " " + cooY);
      // set position of new label here?
      enclosingPanel.revalidate();
    }
  }
}

将新面板添加到封闭面板(我假设您的示例中为panel_1)是一个小小的黑魔法&#39;对我来说 - 除非那个小组有一个特殊的布局管理员,或者你已经扩展了JPanel以便add()意味着什么特别的东西,我不知道它将如何做任何有用的事情。但是这个更加填充的方法显示了获取现有标签坐标的位置,一种让面板包含两个标签的方法,以及我希望你设置新位置的建议标签

这里有很多假设,因为你还没有向我们展示可执行代码。我知道从较大的系统中提取运行代码很困难,但要注意(您和其他读者)对不完整代码的任何答案部分基于填补它的假设,部分基于未做出的假设还有什么需要或在别处编码。