0

这是情况。

带有 JLabel 的 Items 抽象类label,以及display()通过将 JLabel 添加到 JPanel 来在屏幕上显示项目的功能:

public abstract class Items {

    public JLabel label;

    // to add label to panel (display on screen)
    public abstract void display(JPanel panel);
}

具体实现:

public class ConcreteItem extends Items {

    public ConcreteItem() {
        // set the label of concrete item
        ImageIcon icon = new ImageIcon(new URL("https://..."));
        this.label = new JLabel(icon);
    }
    @Override
    public void display(JPanel panel) {
        panel.add(this.label);
    }
}

装饰师:

public abstract class ItemDecorator extends Items {

    public Items decoratedItem;

    public ItemDecorator(Items decoratedItem){
        super();
        this.decoratedItem = decoratedItem;
    }

    @Override
    public void display(JPanel panel) {
        this.item.display(panel);
    }

}

和混凝土装饰器:

public class ConcreteDecorator extends ItemDecorator {

    public ConcreteDecorator(Items decoratedItem) {
        super(decoratedItem);

        // set the label of concrete decorator
        ImageIcon icon = new ImageIcon(new URL("https://..."));
        this.label = new JLabel(icon);
    }

    @Override
    public void display(JPanel panel) {
        super.display(panel);
        panel.add(this.label); // add label of concrete decorator to the screen
    }
}

和客户端类:

public class Client {
    public Client() {

        Jpanel panel = new JPanel();

        // create item with decorators (these are created somewhere else, furthur being returned to Client class)
        ConcreteItem concreteItem = new ConcreteItem();
        ConcreteDecorator decorator = new ConcreteDecorator(concreteItem);

        // and this is the only stuff in Client class
        Items item = decorator;

        // display all elements on screen
        item.display(panel);
    }
}

因此,当我创建一个Items由 a 装饰的对象时ConcreteDecorator,该display()函数应将所有标签添加到面板。我想在运行时将 ConcreteDecorator 中标签的可见性设置为false,即label.setVisible(false),以便将其从屏幕上删除。我怎样才能从只有item对象的 Client 类中做到这一点?

4

2 回答 2

0

作为flag一个公共字段,您应该能够从Client类中调用它:

item.flag = false;

虽然有点奇怪的类层次结构......

于 2019-12-15T13:19:24.150 回答
0

由于flag它是一个公共字段,因此您可以在任何可以访问 实例的地方更改它Items,例如:

public class ConcreteDecorator extends ItemDecorator {

    public ConcreteDecorator(Items item) {
        super(item);
    }

    @Override
    public void display() {
        item.flag = false; // <<< change flag here
        super.display();
        System.out.print("Adding decorators to Item...");
    }
}

除了装饰器模式,你应该有更严格的可见性;private尽可能使用protected

于 2019-12-15T11:34:23.167 回答