Lwjgl GUI库

时间:2014-02-09 15:04:18

标签: java oop design-patterns user-interface lwjgl

我正在尝试自己创建一个小的lwjgl GUI库。我现在又开始了3次。我的问题是我无法创建一个好的OOP设计。 我查看了Swing和AWT库中内置的Java。 我读了这些代码,并研究了Swing和AWT的类设计。 但我认为这不是为lwjgl创建自己的GUI库的正确方法,因为它有很多不同之处。 我在OO中遇到的最大问题之一是我无法达到某种方法。我认为这是一个普遍的编程问题。例如,我有以下类:

    class Container {

        private ArrayList<Component> components = new ArrayList<Component>();

        public void add(Component c) { // Accepts only Component objects, or child objects of Component

            this.components.add(c);
        }

        public volid paintAll() {

            for(int i = 0; i < this.components.size(); i++) {

                 // Not possible, the Component object has no method paintComponent(), the
                 // class which extends Component does. This can be a button, but it's stored as 
                 // a Component. So the method paintComponent "Does not exist" in this object,  
                 // but is does.
                 this.components.get(i).paintComponent(); // error
            }
        }
    }

class Component {

    private int x;
    private int y;
    private int width;
    private int height;

    /* methods of Component class */
}

class Button extends Component {

    private String text;

    public Button(String text) {

        this.text = text;
    }

    public void paintComponent() {

        /* Paint the button */

    }
}

// In Swing, the Component class has no method like paintComponent.
// The container can only reach the methods of Component, and can not use methods of
// classes which extends Component.
// That's my problem. How can I solve this?

Container container = new Container();
Button b = new Button("This is a button");
Container.add(b); // b "Is a" Component.

2 个答案:

答案 0 :(得分:2)

您需要确保 Component的每个子类都有paintComponent()方法。您可以通过在超类中将其声明为抽象来实现:

abstract class Component {

  /* fields of Component class */

  public abstract void paintComponent();

}

这将强制Component的每个非抽象子类实现该方法,否则编译器将产生错误。

Swing做同样的事情:JComponenta method paint(Graphics)


除此之外:因为Component已经存在于类的名称中,所以更常见的是命名方法paint()。这避免了呼叫中的重复,例如myComponent.paint()代替myComponent.paintComponent()

答案 1 :(得分:1)

如果您需要将按钮存储为组件,可以使用instanceof运算符检查它们是否实际上是按钮,然后通过像这样的方式调用只有按钮的方法:

for(int i = 0; i < this.components.size(); i++) {
    if(components.get(i) instanceof Button){
        Button b = (Button)components.get(i);
        b.paintComponent(); //or any other methods that buttons have.
    }
    //treat it as a normal component;
}

或者,你可以将你的按钮分别存储在不是按钮的组件上,然后不需要投射它们。