英文:
How to reuse a common panel?
问题
我有一个用于向购物车添加物品的面板。例如:
public class SomePanel extends JPanel {
private static final long serialVersionUID = 1L;
private JLabel firstLabel;
private JLabel secondNameLabel;
private JLabel thirdLabel;
// and more..
private JTextField firstTextField;
private JTextField secondTextField;
private JTextField thirdTextField;
// and more..
private void init() {
firstLabel = new JLabel("First label");
secondLabel = new JLabel("Second label");
thirdLabel = new JLabel("Third label");
// and more..
firstTextField = new JTextField("first field");
secondTextField = new JTextField("second field");
thirdTextField = new JTextField("third field");
// and more..
}
}
这个面板位于对话框中。当我在菜单中选择“添加”时,会出现一个对话框和这个面板。在那里,我可以输入有关产品的信息并添加产品。
问题是,在主表单上我还有另外三个区域。这些区域也显示与上面相同的面板。我应该如何重用现有的 SomePanel
,这样做是否是一个好的做法?也许为每个元素(JLabel
和 JTextField
)创建单例会更好吗?也许有一些特殊的模式可以解决这个问题?
英文:
I have a panel for adding an item to the cart. For example:
public class SomePanel extends JPanel {
private static final long serialVersionUID = 1L;
private JLabel firstLabel;
private JLabel secondNameLabel;
private JLabel thirdLabel;
// and more..
private JTextField firstTextField;
private JTextField firstTextField;
private JTextField thirdTextField;
// and more..
private void init() {
firstLabel = new JLabel("First label");
secondLabel = new JLabel("Second label");
thirdLabel = new JLabel("Third label");
// and more..
firstTextField = new JTextField("first field");
secondTextField = new JTextField("second field");
thirdTextField = new JTextField("third field");
// and more..
}
This panel is located in the dialog. When I select "Add" in the menu, a dialog and this panel appear. There I can enter information about the product and add the product.
The problem is that I have another three areas on the main form. These areas also display the same panel as above. How can I reuse an existing SomePanel
and would this be a good practice? Maybe it's better to create singletons for each element (JLabel
and JTextField
) instead?
Maybe there is some special pattern for solving this problem?
答案1
得分: 1
这是一个优秀的建议,可以重新使用面板对象,而且不仅适用于固定数量的字段,还可以用于动态数量的字段。
您已经在一个JPanel周围创建了一个包装器,所以我们可以简单地在其中添加一个方法,以更新面板以显示新内容。在这种情况下,我创建了一个名为create(...)
的新方法,它将更新内容。
例如,如果您有固定数量的字段,代码可能如下所示:
public class SomePanel extends JPanel {
// ... (省略其他成员变量和构造函数)
// 新方法用于更新内容
public boolean create(List<String> labels, List<String> textFields) {
if(labels.size() != textFields.size()){
System.out.println("无法更新面板,标签数量与字段数量不同");
return false;
}
// 更新固定的标签和字段值
firstLabel.setText(labels.get(0));
secondLabel.setText(labels.get(1));
thirdLabel.setText(labels.get(2));
firstTextField.setText(textFields.get(0));
secondTextField.setText(textFields.get(1));
thirdTextField.setText(textFields.get(2));
// 在更新值后确保此面板可见
this.setVisible(true);
// 成功,返回true
return true;
}
// ... (省略其他方法)
}
或者,如果您想要使用灵活数量的标签和字段来创建动态内容,可以尝试以下代码:
public class SomePanel extends JPanel {
// ... (省略其他成员变量和构造函数)
// 新方法用于更新内容
public boolean create(List<String> labels, List<String> textFields) {
if(labels.size() != textFields.size()){
System.out.println("无法更新面板,标签数量与字段数量不同");
return false;
}
// 移除先前的组件
this.removeAll();
// 重置动态列表(如果您需要从面板编辑/检索数据)
fieldList = new ArrayList<>();
// 放置值(如果使用布局管理器,则删除这些)
int xPos = 0;
int yPos = 0;
// 根据新值更新列表
for (int count = 0; count < labels.size(); count++) {
// 创建并添加标签
JLabel dynamicLabel = createLabel(labels.get(count), xPos, yPos);
this.add(dynamicLabel);
// 更新位置,如果使用布局管理器,请删除此部分
yPos += labelHeight + padding;
// 创建并添加字段
JTextField dynamicField = createField(textFields.get(count), xPos, yPos);
this.add(dynamicField);
// 更新位置,如果使用布局管理器,请删除此部分
yPos += fieldHeight + padding;
// 将字段存储在列表中,以便以后可以检索内容,或者如果需要从用户那里编辑
fieldList.add(dynamicField);
}
// 在更新值后确保此面板可见
this.setVisible(true);
// 成功,返回true
return true;
}
// ... (省略其他方法)
}
以上是您提供的代码的翻译部分。如果您有任何其他问题或需要进一步的帮助,请随时提问。
英文:
It is an excellent suggestion to re-use the panel object, and it doesn't just work for a fixed number of fields, you can do it with a dynamic number of fields as well.
You have already created a wrapper around a JPanel, so we can simply add a method to it that will update the panel to display the new contents. In this case I have created a new method create(...)
that will update the contents.
For example, if you have a fixed number of fields it might look something like this:
public class SomePanel extends JPanel {
private static final long serialVersionUID = 1L;
final int labelHeight = 10;
final int fieldHeight = 20;
private JLabel firstLabel = createLabel("label 1", 0, 0);
private JLabel secondLabel = createLabel("label 2", 0, 30);
private JLabel thirdLabel = createLabel("label 3", 0, 60);
// and more..
private JTextField firstTextField = createField(null, 0, 10);
private JTextField secondTextField = createField(null, 0, 40);
private JTextField thirdTextField = createField(null, 0, 70);
// and more..
//New method to udpate the contents
public boolean create(List<String> labels, List<String> textFields) {
if(labels.size() != textFields.size()){
System.out.println("Failed to update panel, there was a different number of labels and fields");
return false;
}
//Update the fixed label and field values
firstLabel.setText(labels.get(0));
secondLabel.setText(labels.get(1));
thirdLabel.setText(labels.get(2));
firstTextField.setText(textFields.get(0));
firstTextField.setText(textFields.get(1));
firstTextField.setText(textFields.get(2));
//Make sure that this panel is visiable after updating the values
this.setVisible(true);
//Success, return true
return true;
}
//Remove the x and y depending on the layout manager
private JLabel createLabel(String name, int x, int y){
//Create label
JLabel label = new JLabel(name);
//Set location and size or use a layour manager
label.setLocation(x, y);
label.setSize(50, labelHeight);
//Configure cutsom label settings
//label.setFont(...);
//label.setBorder(...);
//return the custom label
return label;
}
//Remove the x and y depending on the layout manager
private JTextField createField(String content, int x, int y) {
//Create label
JTextField field = new JTextField();
if(content != null){
field.setText(content);
}
//Set location and size or use a layour manager
field.setLocation(x, y);
field.setSize(80, fieldHeight);
//Configure cutsom text field settings
//field.setFont(...);
//field.setBorder(...);
//return the custom field
return field;
}
}
Or if you want to get fancy with dynamic content with a flexible number of labels and fields you could do something like this:
public class SomePanel extends JPanel {
private static final long serialVersionUID = 1L;
final int labelHeight = 10;
final int fieldHeight = 20;
final int padding = 5;
//Keep a list of contents only if you need to edit/retreive data from the panel
private List<JTextField> fieldList = new ArrayList<>();
//New method to udpate the contents
public boolean create(List<String> labels, List<String> textFields) {
if(labels.size() != textFields.size()){
System.out.println("Failed to update panel, there was a different number of labels and fields");
return false;
}
//remove previous components
this.removeAll();
//reset the dynamic lists (For if you need to edit/retreive data from the panel)
fieldList = new ArrayList<>();
//placement values (remove these if using a layout manager)
int xPos = 0;
int yPos = 0;
//Update the lists based on the new values
for (int count = 0; count < labels.size(); count++) {
//Create and add labels
JLabel dynamicLabel = createLabel(labels.get(count), xPos, yPos);
this.add(dynamicLabel);
//update placement location, remove if you use a layout manager
yPos += labelHeight + padding;
//Create and add fields
JTextField dynamicField = createField(textFields.get(count), xPos, yPos);
this.add(dynamicLabel);
//update placement location, remove if you use a layout manager
yPos += fieldHeight + padding;
//Store fields in a list so that we can retreive the contents later if needed, or if
fieldList.add(dynamicField);
}
//Make sure that this panel is visiable after updating the values
this.setVisible(true);
//Success, return true
return true;
}
//Remove the x and y depending on the layout manager
private JLabel createLabel(String name, int x, int y){
//Create label
JLabel label = new JLabel(name);
//Set location and size or use a layour manager
label.setLocation(x, y);
label.setSize(50, labelHeight);
//Configure cutsom label settings
//label.setFont(...);
//label.setBorder(...);
//return the custom label
return label;
}
//Remove the x and y depending on the layout manager
private JTextField createField(String content, int x, int y) {
//Create label
JTextField field = new JTextField();
if(content != null){
field.setText(content);
}
//Set location and size or use a layour manager
field.setLocation(x, y);
field.setSize(80, fieldHeight);
//Configure cutsom text field settings
//field.setFont(...);
//field.setBorder(...);
//return the custom field
return field;
}
//Method to get the current field contents if needed or if edited by the user
public List<JTextField> getCurrentFieldContent (){
return fieldList;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论