2012-10-06 17 views
6

Mam niestandardowy komponent, który rozszerza JComponent, który przesłania metodę paintComponent (Graphics g), ale kiedy próbuję dodać go do mojego JPanela po prostu nie działa, nic nie jest rysowane. Oto mój kod:JComponent not Drawing to JPanel

public class SimpleComponent extends JComponent{ 

int x, y, width, height; 

public SimpleComponent(int x, int y, int width, int height){ 
    this.x = x; 
    this.y = y; 
} 

@Override 
public void paintComponent(Graphics g){ 
    Graphics2D g2 = (Graphics2D) g; 
    g2.setColor(Color.BLACK); 
    g2.fillRect(x, y, width, height); 
} 
} 


public class TestFrame{ 
public static void main(String[] args){ 
    JFrame frame = new JFrame(); 
    JPanel panel = new JPanel(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    panel.setPreferredSize(new Dimension(400, 400)); 
    frame.add(panel); 
    frame.pack(); 
    frame.setResizable(false); 

    SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); 
    panel.add(comp); 
    frame.setVisible(true); 
} 
} 

Odpowiedz

4

Współpracuje - składnik jest dodawany do JPanel, ale jak duże to jest? Jeśli to sprawdzić po GUI zostało wydane, będziesz prawdopodobnie okaże się, że wielkość komponentu wynosi 0, 0.

SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); 
panel.add(comp); 
frame.setVisible(true); 

System.out.println(comp.getSize()); 

Rozważ swoją JComponent przesłonić getPreferredSize i powrócić do wymiaru, który ma sens:

public Dimension getPreferredSize() { 
    return new Dimension(width, height); 
} 

Jeśli chcesz użyć x i y, możesz również zastąpić getLocation().

Edytuj
Musisz również ustawić pola szerokości i wysokości!

public SimpleComponent(int x, int y, int width, int height) { 
    this.x = x; 
    this.y = y; 
    this.width = width; // *** added 
    this.height = height; // *** added 
} 
+0

To jest naprawdę dziwne, i replikowałem ten problem na Windowsie i Macu i jego zawsze dokładnie to samo – lilroo

+0

Ah, szerokość i wysokość jest ustawiona na zero – lilroo

+0

Po zapamiętaniu, aby ustawić pola szerokości i wysokości to nadal nie działało, ale kiedy nadpisałem metodę getPreferredSize() zadziałało. – lilroo

-2

Whoaa! Absolutnie nie jest właściwą odpowiedzią!

Pierwszym absolutnym zobowiązaniem jest CARDINAL SIN, aby zrobić to wszystko w wątku innym niż EDT !!! Nie ma tu miejsca, by to wyjaśnić ... w sieci jest tylko około 30 miliardów miejsc, aby się o tym dowiedzieć.

Gdy cały ten kod jest wykonywany w Runnable w (Dispatch temat zdarzeń) EDT, a następnie:

nie

Trzeba zastąpić preferredSize (chociaż można, jeśli chcesz), ale ... musisz to ustawić.

Absolutnie nie należy ustawić rozmiary (height i width lub setSize()) bezpośrednio!

Co robisz musisz zrobić, to aby uzyskać java.awt.Container, panel, w przykładzie, aby „położyć się na zewnątrz” ... nie jest to metoda Container.doLayout(), ale jak mówi w dokumentacji API:

Powoduje, że ten pojemnik rozkłada swoje komponenty. Większość programów nie powinna wywoływać bezpośrednio tej metody, ale powinna wywoływać metodę sprawdzania poprawności .

rozwiązaniem jest zatem:

SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); 
comp.setPreferredSize(new Dimension(90, 90)); 
panel.add(comp); 

// the key to unlocking the mystery 
panel.validate(); 

frame.setVisible(true); 

Nawiasem mówiąc, proszę skorzystać z mojego doświadczenia: Spędziłem wiele godzin łzawienie moje włosy próbując zrozumieć to wszystko validate, invalidate, paintComponent, paint itp rzeczy ... i Wciąż czuję, że tylko podrapałem powierzchnię.

+0

Zobacz http://stackoverflow.com/questions/10866762/use-of-overriding-getpreferredsize-instead-of-using-setpreferredsize-for-fix?rq=1 –

+0

OK dzięki ... ale jeśli byłeś osobą Który ujął tutaj moją odpowiedź, która nie była zbyt pomocna przyszłym odwiedzającym to pytanie: moja odpowiedź jest znacznie lepsza niż przyjęta odpowiedź, a niuans na temat 'setPreferredSize' /' getPreferredSize' tego nie zmienia. –

+0

Och ... Widzę, że jesteś odpowiedzią na zaakceptowaną odpowiedź! Ale z przedstawicielem 214k musisz na pewno wiedzieć, że każdy punkt, który powiedziałem, jest właściwy, i że twoja odpowiedź naprawdę, um, jak to ujęłam, pozostawia pole do ulepszeń! –