PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bild in einem JFrame anzeigen


minos5000
2007-08-13, 21:59:24
Hi,

im folgenden einmal das Codestück, das die Anzeige des Bildes in dem Frame bewirken soll:


public class ImageComponent extends JComponent {

private Image image;

public ImageComponent(Image image) {
this.image = image;
}

public void paintComponent(Graphics g) {
g.drawImage(image,0,0,null);
}
}



public class Gui extends JFrame {

...

private void openMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & GIF Images", "jpg", "gif");
jFileChooser1.setFileFilter(filter);
int returnVal = jFileChooser1.showOpenDialog(Gui.this);

if(returnVal == jFileChooser1.APPROVE_OPTION) {
selectedFile = jFileChooser1.getSelectedFile().getPath();
}

File imageFile = new File(selectedFile);
try {
Image image = ImageIO.read(new File(selectedFile));
ImageComponent imageComponent = new ImageComponent(image);

Graphics g = Gui.this.getGraphics();
g.drawImage(image,640,480,Gui.this);

//Gui.this.getContentPane().add(imageComponent);
//Gui.this.getContentPane().validate();


} catch(IOException e) {
System.out.println(e.toString());
}


}

...
}



Ich hatte die Anzeige mal mit den beiden auskommentierten "getContentPane()"-Befehlen versucht, aber das hat leider auch nicht funktioniert. Seltsamerweise gings, wenn ich einen neuen Frame erstelle und dem vor dem Anzeigen mit getContentPane die ImageComponent anhänge.
Eine Lösung die ich gefunden habe macht das z.B. mit einem JLabel, dem als Icon das entsprechende Bild übergeben wird, aber das muß doch auch anders zu machen sein.



Ciao,
minos

Shink
2007-08-14, 08:27:51
Ohne jetzt genauer darüber nachzudenken: Die paint() bzw. paintComponent()-Methode des JFrames überschreibt dir das Bild vermutlich beim nächsten repaint().

minos5000
2007-08-14, 15:22:54
Hmm, daß so was passieren kann, davon hab ich bisher noch nichts gelesen. Wie könnte man das denn abstellen?

RMC
2007-08-14, 18:05:46
Hmm, daß so was passieren kann, davon hab ich bisher noch nichts gelesen. Wie könnte man das denn abstellen?

Das Zeichnen passiert automatisch, da musst du nicht viel dazu tun. Paint() und paintComponent() sind Methoden von den AWT/Swing-Komponenten und werden automatisch aufgerufen, wenn es Java für notwendig hält (zb wenn du das Fenster bewegst).


Dein ImageComponent hat schon eine eigene paint-Methode, die du überschrieben hast. D.h. dieser Teil hier


Graphics g = Gui.this.getGraphics();
g.drawImage(image,640,480,Gui.this);


ist nicht notwendig. Du musst das ImageComponent nur dem parent hinzufügen, das Zeichnen im Szenengraph passiert dann automatisch. Also ich würde die auskommentierte Zeile


Gui.this.getContentPane().add(imageComponent);


stattdessen wieder "einkommentieren" ;)

EDIT: Wenn du so nichts siehst muss es an etwas Anderem liegen, aber das ist prinzipiell der richtige Weg.

minos5000
2007-08-15, 08:40:10
Das der Weg über getContentPane() der richtige ist, hab ich gestern auch in Java ist eine Insel gelesen. Die Tutorial gehen ja meist in medias res und daher hab ich mir von Anfang noch mal durchgelesen wie das Zusammenspiel zwischen Swing und den Graphics Komponenten ist.

Aber eine Erklärung, warum nichts angezeigt wird hab ich immer noch nicht :-/


EDIT:

Mir viel da grad was auf. Könnte der Grund für das Problem die etwas eigene Handlungsweise von NetBeans sein, welches ich zum bauen der GU verwende? Um Elemente zur GUI hinzuzufügen geht NetBeans nämlich folgendermasen vor:

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(drawPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 26, Short.MAX_VALUE)
.addComponent(drawPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
);

Vielleicht beißt sich das ja, wenn ich später mit einem simplen getContentPane().add(...) selber versuch Komponenten hinzuzufügen??

RMC
2007-08-15, 11:19:08
Ich glaube es liegt daran, dass dein ImageComponent keine Größe hat. Außerdem, was für ein Layout verwendest du? Wenn du X/Y genau angeben kannst verwende einfach das Null-Layout:


Gui.this.setLayout(null);
imageComponent.setBounds(0,0,640,480);
getContentPane().add(imageComponent);

minos5000
2007-08-15, 14:42:07
Jipiee, ich konnte das Problem lösen.

Es hatte tatsächlich mit dem gesetzten Layout zu tun. Wenn man dem ContentPane ein Layout zugewiesen hat, dann scheint es nicht mehr möglich zu sein, über getContentPane().add(...) etwas hinzuzufügen, sondern man muß das über die vom Layout zur Verfügung gestellten Funktionen machen.

Eigentlich logisch, aber trotzdem muß man erst mal drauf kommen.