Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing an object of unknown type as parameter in a Java method

Tags:

java

object

I'm creating a couple of classes to simplify processes like creating GUIs, applying accessibility settings, drawing graphics, etc. and I've come a long way; but I've had an idea that would be great it if could work, and I'm wondering if it's possible.

Right now, I have a "JFrameBuilder" class, with methods like:

/**
 * 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;
        }
    }

So basically all it's really doing is setting multiple properties in one method (eliminating the need to write 10-15 lines of code per object). These work great, but I'd like to abstract it further, to where the methods can work with JApplets, JPanels and other containers as well as JFrames. That way I could generalize the class from JFrameBuilder to a more straightforward "AppBuilder", "GUIBuilder" etc. and be able to use it in other projects.

But to do this, I would need to pass an object of an unknown type as a parameter in the methods. So I tried replacing "JFrame" with "Object", then using a String to identify its type, and tried to make changes based on that. However, I ran into some trouble using methods like "add"; I'm thinking it's because Object doesn't have an add method (even though a JPanel was the object type and JPanel does).

To clarify a bit, basically what I need it to do is figure out the container where the button/label/whatever should be added (the "parent?"). And so far, the only way I know to do that is by passing it as a parameter in a method; if there's another way, I'd like to learn it, but if not, then ideally passing an unknown-type variable seems to be the best way. That way there would be something inside the method to identify the type and base its next actions on that (like for example, if can display other objects, add to it, and if not, catch the exception).

So I checked out similar questions on this site (which was actually where I got the Object idea from) and also Googled around a bit, but with no luck. So as always, I would definitely appreciate any suggestions or other ideas.

Thanks. : )

like image 585
user2403876 Avatar asked Jul 10 '13 02:07

user2403876


1 Answers

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

like image 70
Bnrdo Avatar answered Nov 01 '22 18:11

Bnrdo