我正在建造一个家谱。该应用程序通过使用此代码按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}}
答案 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()
意味着什么特别的东西,我不知道它将如何做任何有用的事情。但是这个更加填充的方法显示了获取现有标签坐标的位置,一种让面板包含两个标签的方法,以及我希望你设置新位置的建议标签
这里有很多假设,因为你还没有向我们展示可执行代码。我知道从较大的系统中提取运行代码很困难,但要注意(您和其他读者)对不完整代码的任何答案部分基于填补它的假设,部分基于未做出的假设还有什么需要或在别处编码。