java képkezelés

Fórumok

Sziasztok!

Java tanulásra adtam a fejem, és egy igen idegesítő problémába ütköztem, és szeretném kérni a segítségeteket.
Dinamikusan szeretnék képeket adni egy JPanle elemhez. A meghívott osztály:

class ImageJPanel extends JPanel {

private Image image, resized;
private double ratio;
private int width, height;

public ImageJPanel(File file, int w, int h) {
if(file != null) {
MediaTracker tracker = new MediaTracker(this);
image = Toolkit.getDefaultToolkit().getImage(file.getAbsolutePath());
tracker.addImage(image, 0);
try {
tracker.waitForID(0);
} catch(InterruptedException e) {

}
width = w;
height = h;
ratio = 1.0*image.getWidth(this) / image.getHeight(this);
addComponentListener(new ComponentAdapter(){
public void componentResized(ComponentEvent e) {
if (ratio > 1) {
resized = image.getScaledInstance((int)width, (int)(getWidth()/ratio), Image.SCALE_SMOOTH);
} else {
resized = image.getScaledInstance((int)height, (int)(getHeight()/ratio), Image.SCALE_SMOOTH);
}
}
});
}
}

protected void paintComponent(Graphics gr) {
super.paintComponent(gr);
gr.drawImage(resized, 0, 0, this);
}
}

A képek rendesen a helyükre is kerülnek, illetve csak kerülnének, mert ahhoz, hogy meg is jelenjenek demaximalizálnom, majd maximalizálnom kell az abalkot, addig semmi. Nem értem ez miért van, és ha valaki fel tudna világosítani, hálás lennék. Köszönöm szépen a válaszokat.

Hozzászólások

nincs valami Invalidate() és/vagy Update() metódus, ami kikényszeríti az újrarajzolást ?

A form setVisible hivasa elott adod hozza a kepeket a panelhez?

Illetve kep hozzaadas utan kell repaint-ot hivni.

épp ez a problémám, hogy a form már megvan, és utólag tölt be egy képet az egyik oldalra, a másik oldalra pedig az aktuális könyvtárban lévő képekből csinál preview nézetet. A könyvtárat akármikor meg tudod változtatni, és változtatás után nem jeleníti meg a képeket csak akkor ha előtte lekicsinyítem az ablakot, majd visszateszem maximalizálttá.

Esetleg a JFrame-t megvalósító osztályban egy show() metódus hívása a JPanel hozzáadása után? Más ötletem nincs. :( Egyelőre

Nem próbáltam most hirtelen ki, de szerintem ez kell neked:

http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Component.html#invalid…()

vagy:

http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Component.html#repaint()

Azt hiszem a különbség az, hogy az invalidate újraelrendezést (layout) és csinál, a repaint meg csak festést. Szélsőséges esetben hívd meg a kettőt egymás után. Valahogy működnie kell.

Ha a könyvtár váltásnál kellene képet cserélni a panelen, akkor talán a könyvtár váltás figyelőjébe kellene a váltás után egy metódus, ami a panelen kivált egy validate()-et, vagy egy pack()-ot. Remélem érted mire gondoltam :)

Több "hiba" is van a kódban, ami abból adódik, hogy valami ősöreg példából dolgozol, illetve nem felelnek meg a Java elvárásoknak...

// Célszerű a feladatra metódust írni
public BufferedImage loadImage(File file, int w, int h)
{
if (file!=null)
{
// Felejtsd el a MediaTracker-t, már akkor elavult volt, amikor megírták
BufferedImage image=ImageIO.read(file);

// Az átméretezés megfelelő, nem idézem be ide
[...]

return image;
}

return null;
}

Ezen túl a helyedben nem a JPanel-be erőszakolnám be a képek megjelenítését - tudom, szinte minden leírást ezt erőlteti - hanem egy JLabel-t használnék erre, mivel ez képes képet megjeleníteni, igaz, ImageIcon-t kell neki átadni, valahogy így:
JLabel label=new JLabel(new ImageIcon(loadImage("valami.png",100,50)));

A label-t pedig oda adod hozzá és akkora méretben, amekkorában akarod... :)

Részedről ott van baj, hogy a Swing nem igazán tud róla, hogy kirajzoltál valami képet, mert erről értesíteni kell, célszerűen meg kell hívni a repaint() metódust.
--
http://www.javaforum.hu

Köszönöm szépen, tökéletesen működik, egy esetet kivéve:
a képet befoglaló JPanel alatt van egy másik JPanel, amiben egy textarea van, amolyan history kiírására. Namármost, ha a textareára teszek egy scrollbart:
statusbar.add(new JScrollPane(status = new JTextArea("system loaded...", 3, 50))); nem jelennek meg a képek, így viszont igen:
statusbar.add(status = new JTextArea("system loaded...", 3, 50));

Ezt nem értem, hisz a két elem (a kép és a textarea) nem is azonos JPanelen vannak. Ennek okát el tudod nekem mondani?

Köszi