2009-08-28 18 views
13

Czy istnieje sposób przekonwertowania pliku JPanel (który nie został jeszcze wyświetlony) do obrazu BufferedImage?Konwersja JPanel do obrazu

Dzięki,

Jeff

+0

Cóż, poddaję się. Dałem ci dwie odpowiedzi w dwóch ostatnich wypowiedziach, które zignorowałeś. Powodzenia w przyszłych postach. – camickr

+0

Doceniam odpowiedzi i nie ignorowałem ich. W tym poście ScreenImage nie był dokładnie tym, czego szukałem i ta metoda zwykłego malowania na innej grafice wydawała mi się właściwym kierunkiem. W okienku dialogowym okazało się, że to nie jest problem i zostałem zalany, więc nie odpowiadałem na wszystko. Doceniam twoje odpowiedzi. –

Odpowiedz

23

Z BufferedImage można utworzyć obiekt graficzny, który można wykorzystać, aby zadzwonić farby na JPanel, coś takiego:

public BufferedImage createImage(JPanel panel) { 

    int w = panel.getWidth(); 
    int h = panel.getHeight(); 
    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g = bi.createGraphics(); 
    panel.paint(g); 
    return bi; 
} 

może być konieczne upewnij się, że najpierw ustawiłeś rozmiar panelu.

+0

ładne, dzięki. czy istnieje sposób, aby dowiedzieć się, jaki powinien być rozmiar panelu (może jego preferowany rozmiar)? –

+0

Uważam, że jest to preferowany rozmiar lub aktualny rozmiar, o ile został już renderowany. Występują problemy, jeśli nie zostały one już renderowane - nie pamiętam dokładnie szczegółów, ale pamiętam, że podczas korzystania z systemu drukowania pamiętam o podobnych właściwościach. – aperkins

+0

Tak, preferowany rozmiar działa, ale jak powiedziałeś, nie wyświetla się, jeśli panel nie jest jeszcze wyświetlany, co nie pomaga mi zbytnio. Czy istnieje sposób, aby "wyrenderować" go, ale nie wyświetlać go na ekranie? Zasadniczo buduję komponent, który musi zostać zapisany do obrazu, ale nie wyświetlany. –

2

Zasadniczo buduję komponent że musi dostać zapisywane na obrazie ale nie wyświetlany

ScreenImage wyjaśnia, jak to zrobić, co chcesz.


Odpowiednia sekcja ScreenImage.java (nieznacznie edytowana). layoutComponent wymusza wszystkie przyciski widoczne na obrazie.

/** 
* @return Renders argument onto a new BufferedImage 
*/ 
public BufferedImage createImage(JPanel panel, int width, int height) { 
    BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 
    Graphics2D g = bi.createGraphics(); 
    panel.setSize(width, height); // or panel.getPreferedSize() 
    layoutComponent(panel); 
    panel.print(g); 
    return bi; 
} 

private void layoutComponent(Component component) { 
    synchronized (component.getTreeLock()) { 
     component.doLayout(); 

     if (component instanceof Container) { 
      for (Component child : ((Container) component).getComponents()) { 
       layoutComponent(child); 
      } 
     } 
    } 
} 
0

Zobacz BasicTableUI. Renderowanie komórki jest rysowane na obrazie bez wyświetlania, a następnie rysowane na widocznym komponencie tabeli.

0

Odpowiedź od Toma jest w zasadzie poprawna, ale wywołanie paint() bezpośrednio nie jest zalecane, ponieważ jest to wywołanie synchroniczne i może przerwać z inną operacją na wątku obrotowym. Zamiast używać paint() powinniśmy używać print() zamiast

public BufferedImage createImage(JPanel panel) { 

int w = panel.getWidth(); 
int h = panel.getHeight(); 
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
Graphics2D g = bi.createGraphics(); 
panel.print(g); 
return bi; 
} 
1

zgadzam się. JPanel.print() jest lepszy. JPanel.paint() prowadzi do błędu w mojej aplikacji.

public BufferedImage createImage(JPanel panel) { 

int w = panel.getWidth(); 
int h = panel.getHeight(); 
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
Graphics2D g = bi.createGraphics(); 
panel.print(g); 
return bi; 
}