如何重用通用面板?

huangapple go评论89阅读模式
英文:

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,这样做是否是一个好的做法?也许为每个元素(JLabelJTextField)创建单例会更好吗?也许有一些特殊的模式可以解决这个问题?

英文:

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(&quot;label 1&quot;, 0, 0);
private JLabel secondLabel = createLabel(&quot;label 2&quot;, 0, 30);
private JLabel thirdLabel = createLabel(&quot;label 3&quot;, 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&lt;String&gt; labels, List&lt;String&gt; textFields) {
if(labels.size() != textFields.size()){
System.out.println(&quot;Failed to update panel, there was a different number of labels and fields&quot;);
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&lt;JTextField&gt; fieldList = new ArrayList&lt;&gt;();
//New method to udpate the contents
public boolean create(List&lt;String&gt; labels, List&lt;String&gt; textFields) {
if(labels.size() != textFields.size()){
System.out.println(&quot;Failed to update panel, there was a different number of labels and fields&quot;);
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&lt;&gt;();
//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 &lt; 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&lt;JTextField&gt; getCurrentFieldContent (){
return fieldList;
}
}

huangapple
  • 本文由 发表于 2020年10月27日 12:56:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/64548511.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定