Pourquoi appeler dispose() sur l'objet Graphique provoquer un Composite de ne pas rendre tous les composants
Après avoir appris que dispose()
doit être appelée sur Graphics
/Graphics2D
objet après utilisation, j'ai décidé de changer mon jeu pour intégrer cette.
Quand j'ai ajouté g2d.dispose()
dans substituée paintComponent(Graphics g)
de JPanel
, mes composants, j'ai ajouté les extensions de JLabel
classe) où pas rendu, j'ai été en mesure de toujours cliquer sur eux, etc, mais ils ne seraient pas peint.
J'ai testé avec un normal JLabel
et JButton
avec le même effet (bien que JButton
est rendu lorsque la souris est dessus).
Donc ma question est de savoir pourquoi cela se produit?
Voici un SSCCE à démontrer:
après décommentant appel à dispose()
dans paintComponent
de MainMenuPanel
classe:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public Test() {
try {
initComponents();
} catch (Exception ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Test();
}
});
}
private void initComponents() throws Exception {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
MainMenuPanel mmp = new MainMenuPanel();
frame.add(mmp);
frame.pack();
frame.setVisible(true);
}
}
class MainMenuPanel extends JPanel {
//create labels for Main Menu
private PopUpJLabel versusesModeLabel;
private PopUpJLabel singlePlayerModeLabel;
private PopUpJLabel optionsLabel;
private PopUpJLabel helpLabel;
private PopUpJLabel aboutLabel;
//create variable to hold background
private Image background;
private Dimension preferredDimensions;
public static String gameType;
public static final String SINGLE_PLAYER = "Single Player", VERSUS_MODE = "VS Mode";
/**
* Default constructor to initialize double buffered JPanel with
* GridBagLayout
*/
public MainMenuPanel() {
super(new GridBagLayout(), true);
try {
initComponents();
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Could not load main menu background!", "Main Menu Error: 0x004", JOptionPane.ERROR_MESSAGE);
System.exit(4);
}
}
/*
* Create JPanel and its components
*/
private void initComponents() throws Exception {
//set prefered size of JPanel
preferredDimensions = new Dimension(800, 600);
background = scaleImage(800, 600, ImageIO.read(new URL("http://photos.appleinsider.com/12.08.30-Java.jpg")));
//create label instances
singlePlayerModeLabel = new PopUpJLabel("Single Player Mode");
singlePlayerModeLabel.setEnabled(false);
versusesModeLabel = new PopUpJLabel("Versus Mode");
optionsLabel = new PopUpJLabel("Options");
helpLabel = new PopUpJLabel("Help");
aboutLabel = new PopUpJLabel("About");
//create new constraints for gridbag
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.HORIZONTAL;
gc.ipady = 50;//vertical spacing
//add newGameLabel to panel with constraints
gc.gridx = 0;
gc.gridy = 0;
add(singlePlayerModeLabel, gc);
gc.gridy = 1;
add(versusesModeLabel, gc);
//add optionsLabel to panel with constraints (x is the same)
gc.gridy = 2;
add(optionsLabel, gc);
//add helpLabel to panel with constraints (x is the same)
gc.gridy = 3;
add(helpLabel, gc);
//add aboutLabel to panel with constraints (x is the same)
gc.gridy = 4;
add(aboutLabel, gc);
}
public static BufferedImage scaleImage(int w, int h, BufferedImage img) throws Exception {
BufferedImage bi;
//bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
bi = new BufferedImage(w, h, img.getType());
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(img, 0, 0, w, h, null);
g2d.dispose();
return bi;
}
/*
* Will return the preffered size of JPanel
*/
@Override
public Dimension getPreferredSize() {
return preferredDimensions;
}
/*
* Will draw the background to JPanel with anti-aliasing on and quality rendering
*/
@Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
//convert graphics object to graphics2d object
Graphics2D g2d = (Graphics2D) grphcs;
//set anti-aliasing on and rendering etc
//GamePanel.applyRenderHints(g2d);
//draw the image as the background
g2d.drawImage(background, 0, 0, null);
//g2d.dispose();//if I uncomment this no LAbels will be shown
}
}
class PopUpJLabel extends JLabel {
public final static Font defaultFont = new Font("Arial", Font.PLAIN, 50);
public final static Font hoverFont = new Font("Arial", Font.BOLD, 70);
PopUpJLabel(String text) {
super(text);
setHorizontalAlignment(JLabel.CENTER);
setForeground(Color.ORANGE);
setFont(defaultFont);
//allow component to be focusable
setFocusable(true);
//add focus adapter to change fints when focus is gained or lost (used for transversing labels with keys)
addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent fe) {
super.focusGained(fe);
if (isEnabled()) {
setFont(getHoverFont());
}
}
@Override
public void focusLost(FocusEvent fe) {
super.focusLost(fe);
setFont(getDefaultFont());
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent me) {
super.mouseEntered(me);
if (isEnabled()) {
setFont(getHoverFont());
}
//call for focus mouse is over this component
requestFocusInWindow();
}
});
}
Font getDefaultFont() {
return defaultFont;
}
Font getHoverFont() {
return hoverFont;
}
}
intéressé par le "où" ...
C'était un commentaire sur la réponse de la mine, qu'il avait à faire avec le redimensionnement d'une image via des Graphismes de sorte qu'il était correct bien que j'ai pris il nous faut le faire dès que l'on travaille avec des objets graphiques
merci pour la clarification - leçon apprise: ne pas croire que tous les commentaires 🙂
OriginalL'auteur David Kroukamp | 2012-12-17
Vous devez vous connecter pour publier un commentaire.
Le truc, c'est que le
Graphics
contexte que vous utilisez danspaintComponent
est créé et fourni par l'appelant (le cadre), qui est également responsable de l'élimination.Vous avez seulement besoin de disposer de
Graphics
lorsque vous le créer vous-même (par exemple en appelantComponent.getGraphics()
). Dans votre cas, vous n'êtes pas de la création, vous êtes juste de casting, donc ne pas appeler dispose dans ce cas.Je ne comprends pas pourquoi vous dites Vous avez seulement besoin de disposer de Graphiques lorsque vous le créer vous-même (par exemple en appelant Composant.getGraphics()). Lorsque vous appelez
Component.getGraphics()
créez-vous une nouvelleGraphics
? Ma compréhension était queGraphics.createGraphics()
fait, mais pas un simplegetGraphics()
. Et de toute façon, je crois que l'appelgetGraphics()
est généralement une mauvaise idée et devrait être évitée.Vous avez raison,
getGraphics
devrait être évité, mais il est explicitement indiqué dans les docs comme un moyen d'obtenir unGraphics
contexte. Aussi,getGraphics
documentation dire: Crée un contexte Graphique..., donc je suppose qu'un nouveau est créé à chaque fois. Bien sûr,BufferedImage.createGraphics
est aussi une façon de créer unGraphics
contexte.OriginalL'auteur Thorsten Dittmar
Parce que
.dispose()
libère vos ressources. Oui, tout.OriginalL'auteur Michael Ardan