2013-07-10 19 views
5

Tworzę kilka klas, aby uprościć procesy, takie jak tworzenie GUI, stosowanie ustawień dostępności, rysowanie grafiki itp. I przeszedłem długą drogę; ale miałem pomysł, że byłoby wspaniale, gdyby mógł działać, i zastanawiam się, czy to możliwe.Przekazywanie obiektu o nieznanym typie jako parametru w metodzie Java

Teraz mam klasy „JFrameBuilder”, za pomocą metod takich jak:

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

więc w zasadzie wszystko to naprawdę robi jest ustawienie wielu właściwości w jednej metody (co eliminuje potrzebę napisania 10-15 linijek kod na obiekt). Działają świetnie, ale chciałbym je jeszcze bardziej rozwinąć, tam, gdzie metody mogą współpracować z JApplets, JPanels i innymi kontenerami, a także JFrames. W ten sposób mogłem uogólnić klasę z JFrameBuilder do bardziej prostego "AppBuilder", "GUIBuilder" itd. I być w stanie używać go w innych projektach.

Ale aby to zrobić, musiałbym przekazać obiekt o nieznanym typie jako parametr w metodach. Tak więc próbowałem zastąpić "JFrame" przez "Object", następnie używając Stringa, aby zidentyfikować jego typ i na tej podstawie próbowałem dokonać zmian. Jednak wpadłem w kłopoty używając metod takich jak "dodaj"; Myślę, że to dlatego, że Object nie ma metody dodawania (mimo że JPanel był typem obiektu, a JPanel to robi).

Aby nieco wyjaśnić, w zasadzie to, czego potrzebuję, to dowiedzieć się, w którym kontenerze znajduje się przycisk/etykieta/cokolwiek innego ("rodzic"). I do tej pory jedynym sposobem, w jaki to zrobię, jest przekazanie go jako parametru w metodzie; jeśli jest inny sposób, chciałbym się tego nauczyć, ale jeśli nie, najlepiej byłoby przekazanie zmiennej nieznanego typu. W ten sposób w metodzie znajdzie się coś, co pozwoli zidentyfikować typ i oprzeć na nim kolejne działania (na przykład, jeśli można wyświetlić inne obiekty, dodać do niego, a jeśli nie, uchwycić wyjątek).

Sprawdziłem podobne pytania na tej stronie (z którego pochodzi pomysł obiektu), a także wyszukiwałam w Google, ale bez powodzenia. Jak zawsze z pewnością doceniam wszelkie sugestie lub inne pomysły.

Dzięki. :)

+0

Twój JFrame nigdy nie jest używany w metodzie .. i nie zrobić return null w catch catch..i nie używaj 'setBounds' ..spójrz na dziedziczenie huśtawki, które ma wiele poziomów (to nie jest dobre), ale możesz znaleźć "JComponent" – nachokk

+0

Typ parametru zależy od tego, co próbujesz zrobić. Może to być tak podstawowe jak 'Container', lub jeśli okno najwyższego poziomu to typ' Window'. Osobiście używam GUI do tworzenia JPanels, a nie do okien na najwyższym poziomie. W ten sposób mogę dodać JPanele do dodania do dowolnego kontenera, który mi się podoba. Przy okazji 'setBounds (....)'? Nie, nie rób tego. Użyj menedżerów układu. –

Odpowiedz

3

Używając Generics, utwórz abstrakcję dla dodania JButton do komponentu T.

Runnable Kod

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); 
    } 
} 

Ponadto, warto przekonać siebie, że Null Layout is Evil i użyć odpowiedniego layout manager dla celów

+0

Piękne! 1+ do góry głosów –

+1

Dzięki. To sprawiło, że mój dzień :) – Bnrdo

+0

Dałem też +1! Chociaż nie mam pojęcia, dlaczego ustawienie samego układu (użycie setLayout jako "null" i użycie "setBounds") byłoby tak straszne, że jest uważane za "złe" (jak dotąd działa doskonale), myślę, że "uderzyłeś w sedno głowa". A kiedy uczę się konwencji i dlaczego niestandardowy układ jest tak zły, jestem pewien, że dostanę, dlaczego tak wielu z nich krzyczało przeciwko niemu. Ale twój komentarz był zdecydowanie najlepszą informacją, jaką kiedykolwiek otrzymałem na tej stronie - nie tylko krytyką, ale rzeczywistą sugestią + kilkoma linkami (aby móc to dalej zbadać) + działający przykład! Dzięki! :) – user2403876

0

Chcesz metodę dynamiczną, która będzie akceptować różne typy do wykonywania różnych działań na nich. Nie wydaje mi się, że istnieje możliwość dodania go bez znajomości metody, ponieważ logika dodawania przycisku do kontenera powinna być wyraźnie opisana.

Najlepszą opcją jest użycie parametru. Nie polecam używania typu Object, więc najlepszą opcją wydaje się być java.awt.Container. Jeśli masz zamiar użyć obiektu jako typ będziesz musiał rzucić to w zależności od typu atrybutu wspomniałeś -

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

Ale co ja zalecane jest użycie super klasy niż powyższego podejścia. Mam nadzieję, że to ci pomoże.

Powiązane problemy