2010-10-03 10 views
4

J'ai trois questions/problèmes. (NOTE - Je n'ai pas assez de réputation pour poster des photos, donc je les ai liées et j'ai dû les obfusciter ...)Java - JFrame, JPanel, Layout et Clipping

1) J'ai créé un panneau qui contient mes graphiques de jeu (la zone du joueur). Le panneau est censé être 800x800 et couper tout ce qui se trouve en bas et à droite. Mais quand j'ajoute le panneau graphique à un JFrame, il ne clipse pas. Les images vont donc à droite et à gauche. Ceci est une image de la façon dont le jeu commence. Idéalement, les graphiques commenceraient dans ce rectangle tout le temps:

Photo n ° 1: http://i.stack.imgur.com/idL8f.png

Maintenant, voici ce qui se passe quand je presse la lecture pour commencer.

Image # 2: http://i.stack.imgur.com/dxtbe.png

Comment puis-je régler le panneau/châssis de sorte que les graphiques occupent seulement 800x800 (comme la première image) et tout le reste est clipsé?

2) Je suis un peu confus sur la façon dont je peux configurer le JFrame. Voilà comment je veux qu'il layed sur être:

Image # 3: http://i.stack.imgur.com/ZyJS5.png

Comment voulez-vous poser les JFrame/panneaux dehors? Je pensais BorderLayout, mais je ne suis pas certain que ça marcherait.

3) Pour ce jeu, ma classe qui étend JFrame contient aussi main(). Est-ce une mauvaise pratique? ** Êtes-vous censé ne pas étendre JFrame sur la classe principale?

+0

Modifié; s'il vous plaît revenir si incorrect. – trashgod

+0

Voulez-vous dire _clipping_, _cropping_ ou _scaling_? – trashgod

+0

@trashgod: Je veux dire, je veux que le jeu soit contenu et montre le rectangle 800x800 à l'origine. Je ne veux pas que le panneau MONTRERA quelque chose par les 800 pixels dans les directions x et y. (Ainsi, les images débordantes dépasseront toujours 800 dans chaque direction, mais ne seront pas affichées.) –

Répondre

3

1) Le moyen le plus simple d'obtenir un panneau 800x800 est d'utiliser setPreferredSize() puis pack() le JFrame qui l'est. Commodément, pack() "Cette taille Window doit être adaptée à la taille et à la disposition de ses sous-composants."

2). Voir A Visual Guide to Layout Managers pour les suggestions de disposition. Vous pouvez utiliser des panneaux imbriqués pour obtenir la disposition souhaitée.

3). Il n'y a rien mauvais avec extension JFrame, mais il y a peu de point, sauf si vous modifiez le comportement de JFrame. En revanche, JPanel est un conteneur pratique pour regrouper des composants; il a été conçu pour être étendu. Vous pourriez examiner ce example à cet égard.

Addendum:

Je ne veux pas le panneau de montrer quoi que ce soit, mais les 800 pixels dans la direction x et y.

Vous pouvez remplacer paintComponent() et copier la partie de l'image souhaitée. Dans l'exemple ci-dessous, g.drawImage(img, 0, 0, null) dessine les 800 pixels en haut à gauche de l'image, tandis que g.drawImage(img, 0, 0, getWidth(), getHeight(), null) met à l'échelle la taille de l'image. Notez que f.setResizable(false) empêche de modifier la taille de la fenêtre.

Addendum: Vous pouvez également copier des parties arbitraires de l'image source vers des zones arbitraires du panneau de destination, comme illustré ci-dessous.

import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel;

/** @see http://stackoverflow.com/q/3851847 */ 
public class MyPanel extends JPanel { 

    private BufferedImage img; 

    public MyPanel() { 
     this.setPreferredSize(new Dimension(800, 800)); 
     try { 
      img = ImageIO.read(new File("../scratch/image.png")); 
     } catch (IOException ex) { 
      ex.printStackTrace(System.err); 
     } 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
//  g.drawImage(img, 0, 0, 800, 800, null); 
//  g.drawImage(img, 0, 0, getWidth(), getHeight(), null); 
     g.drawImage(img, 0, 0, 800, 800, 0, 0, 800, 800, this); 
    } 

    private void display() { 
     JFrame f = new JFrame("MyPanel"); 
//  f.setResizable(false); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(this); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new MyPanel().display(); 
      } 
     }); 
    } 
} 
+0

Pour le numéro 3, qu'est-ce que le comportement modificateur entraînerait? Est-ce que l'extension et l'instanciation de JFrame changent la façon dont on est autorisé à utiliser le JFrame de quelque façon que ce soit? –

+0

@Dan James: Voir aussi http://forums.sun.com/thread.jspa?threadID=5384235 – trashgod

+0

@Dan James: J'ai ajouté un exemple basé sur ma compréhension de votre commentaire ci-dessus. – trashgod