Question

Mon principal problème concerne le morceau de code suivant lors de la configuration d'un JFrame:

  1. Pourquoi le panneau ne s'affiche pas si j'utilise le pack() et comment le faire fonctionner ?

  2. Pourquoi le premier requestFocusInWindow() ne fonctionne pas et quel est le principe pour l'utiliser ?

  3. Pourquoi le gestionnaire de mise en page par défaut de JPanel ne fonctionne pas si je supprime le setLayout()?


public class SoundGUI extends KeyAdapter{

public static void main(String[] args) {
    SoundGUI sGUI = new SoundGUI();
    sGUI.setUp();
}
public void setUp () {
    JFrame frame = new JFrame ("Key test");
    frame.setSize (1000, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible (true);

    Panel p = new Panel ();
    p.setLayout(new BorderLayout());//why this sentence is necessary  FlowLayout doesn't fill the container but rather lets components size to their preferredSizes.
    p.addKeyListener (this);
    p.requestFocusInWindow();//it's useless here
    //requestFocus only works on focusable components that are displayed.
    MyDrawPanel dp = new MyDrawPanel();
    dp.setBackground(Color.darkGray);

    JLabel test = new JLabel("a trial");
    JButton t = new JButton("b");
    dp.add(t);
    dp.add (test);
    p.add (dp);     
    frame.getContentPane().add(p);
    p.requestFocusInWindow();
    //frame.pack();//why it doesn't work
    //frame.setVisible(true);
}
class MyDrawPanel extends JPanel { 
    public void paintComponent (Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.white);
        for (int i = 0; i < 1000; i += 42) {
            g2.fill3DRect(i,100 ,20 ,80 ,true);
        }
        g2.setColor(Color.black);
        for (int i = 21; i < 1000; i += 42) {
            g2.fill3DRect(i,100 ,20 ,80 ,true);
        }
    }
}
} 
Était-ce utile?

La solution

Suggestions:

  • Appel setVisible(true) après appel pack().C'est logique, n'est-ce pas ?
  • BorderLayout dira à MyDrawPanel de remplir le conteneur p, puisque le composant est ajouté par défaut (c'est-à-dire BorderLayout.CENTER), et c'est ainsi que fonctionne BorderLayout.
  • FlowLayout ne remplit pas le conteneur mais laisse plutôt les composants redimensionner à leurs tailles préférées.
  • Ne mélangez pas Swing avec des composants AWT.c'est-à-dire, n'utilisez pas de panneaux, mais utilisez plutôt JPanels.
  • requestFocus ne fonctionne que sur les composants pouvant être focalisés qui sont affichés.
  • Mieux vaut utiliser des liaisons de touches que des KeyListeners.
  • Mieux vaut éviter de définir la taille de quoi que ce soit si possible.

D'après votre nouveau code, votre problème est dû au fait que vous appelez setSize().La plupart des gestionnaires de mise en page ne respectent pas cela mais plutôt la taille préférée.Si votre dessin JPanel doit être si grand, faites-le.Par exemple, essayez :

class MyDrawPanel extends JPanel {
  private static final int PREF_W = 1000;
  private static final int PREF_H = 300;

  public void paintComponent(Graphics g) {
     super.paintComponent(g); //!!   ******** don't forget this!!! *********
     Graphics2D g2 = (Graphics2D) g;
     g2.setColor(Color.white);
     for (int i = 0; i < 1000; i += 42) {
        g2.fill3DRect(i, 100, 20, 80, true);
     }
     g2.setColor(Color.black);
     for (int i = 21; i < 1000; i += 42) {
        g2.fill3DRect(i, 100, 20, 80, true);
     }
  }

  // the getPReferredSize will make this JPanel preferentially be this size
  @Override
  public Dimension getPreferredSize() {
     return new Dimension(PREF_W, PREF_H);
  }
}

Notez également que le focus de la demande fait fonctionne si le composant est focalisable :

  JPanel p = new JPanel(); //!! This should be a JPanel, not a Panel
  p.setFocusable(true); //!! This is needed
  p.setLayout(new BorderLayout());
  p.addKeyListener(this);
  p.requestFocusInWindow();

Mais notez également que les KeyListeners doivent être évités.Utilisez plutôt les liaisons de touches.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top