6

我正在创建几个类来简化创建 GUI、应用可访问性设置、绘制图形等过程,而且我已经走了很长一段路;但我有一个想法,如果可行的话会很棒,我想知道这是否可能。

现在,我有一个“JFrameBuilder”类,其方法如下:

/**
 * The "addButton" method adds a button to a JFrame
 * @param app The parent window (a JFrame)
 * @param text The button text
 * @param x The x-coordinate where the button should appear
 * @param y The y-coordinate where the button should appear
 * @param width The width of the button
 * @param height The height of the button
 * @return A JButton object (it returns an object so programs can manipulate it later)
 */
public JButton addButton(JFrame app, String text, int x, int y, int width, int height) {
        try {
            JButton button = new JButton();
            button.setText(text);
            button.setBounds(x, y, width, height);
            app.add(button);
            System.out.println("\"" + text + "\" button created.");
            return button;
        }catch(Exception e) {
            System.out.println("Something went wrong when creating the \"" + text + "\" button.");
            System.out.println(e.getStackTrace());
            return null;
        }
    }

所以基本上它真正做的就是在一种方法中设置多个属性(消除每个对象编写 10-15 行代码的需要)。这些工作很好,但我想进一步抽象,这些方法可以与 JApplets、JPanels 和其他容器以及 JFrame 一起使用。这样我就可以将 JFrameBuilder 类概括为更直接的“AppBuilder”、“GUIBuilder”等,并能够在其他项目中使用它。

但要做到这一点,我需要在方法中传递一个未知类型的对象作为参数。所以我尝试用“Object”替换“JFrame”,然后使用字符串来识别它的类型,并尝试在此基础上进行更改。但是,我在使用“add”之类的方法时遇到了一些麻烦;我认为这是因为 Object 没有 add 方法(即使 JPanel 是对象类型而 JPanel 有)。

为了澄清一点,基本上我需要它做的是找出应该添加按钮/标签/任何内容的容器(“父级?”)。到目前为止,我知道的唯一方法是将其作为参数传递给方法;如果有另一种方法,我想学习它,但如果没有,那么理想情况下传递一个未知类型的变量似乎是最好的方法。这样,方法内部就会有一些东西来识别类型并以此为基础(例如,如果可以显示其他对象,添加到它,如果不能,则捕获异常)。

所以我在这个网站上查看了类似的问题(这实际上是我从中获得 Object 想法的地方)并且也用 Google 搜索了一下,但没有运气。因此,与往常一样,我绝对会感谢任何建议或其他想法。

谢谢。:)

4

2 回答 2

4

Using Generics, create an abstraction for adding the JButton to the T component.

Runnable Code

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class AdderExample {
    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("Demo");
                frame.getContentPane().setLayout(new BorderLayout());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                /* Use JFrameAdder if you want to add to a JFrame
                 * ---------------------------------------------- */
                JPanel panel = new JPanel();
                addButton(panel, new JPanelAdder(), "blah", 10, 10, 100, 10);
                frame.getContentPane().add(panel);

                frame.pack();
                frame.setVisible(true);
            }
        });
    }
    public static <T> JButton addButton(T app, Adder<T> adder, String text, int x, int y, int width, int height) {
        try {
            JButton button = new JButton();
            button.setText(text);
            button.setBounds(x, y, width, height);
            adder.add(button, app);
            System.out.println("\"" + text + "\" button created.");
            return button;
        }catch(Exception e) {
            System.out.println("Something went wrong when creating the \"" + text + "\" button.");
            System.out.println(e.getStackTrace());
            return null;
        }
    }
}
interface Adder<E>{
    void add(JButton btn, E e);
}

class JFrameAdder implements Adder<JFrame>{
    @Override
    public void add(JButton btn, JFrame e) {
        e.getContentPane().add(btn);
    }
}
class JPanelAdder implements Adder<JPanel>{
    @Override
    public void add(JButton btn, JPanel e) {
        e.add(btn);
    }
}

Also, you might want to convince your self that Null Layout is Evil and use appropriate layout manager for your purpose

于 2013-07-10T03:02:03.413 回答
0

您需要一个动态方法,该方法将接受不同的类型来对它们执行不同的操作。我认为在不了解方法的情况下添加它是不可能的,因为应该明确描述将按钮添加到容器的逻辑。

最好的选择是使用参数。我不推荐使用 Object 类型,所以最好的选择似乎是java.awt.Container. 如果您打算使用 Object 作为类型,则必须根据您提到的 type 属性对其进行强制转换-

if(object.type.equals("Container")){
  Container container = object; 
}

但我推荐的是使用比上述方法的超类。希望这对您有所帮助。

于 2013-07-10T02:48:45.963 回答