Frage

Mein Hauptproblem ist der folgende Code beim Einrichten eines JFrame:

  1. Warum wird das Panel nicht angezeigt, wenn ich das benutze pack() und wie funktioniert es?

  2. Warum der erste requestFocusInWindow() funktioniert nicht und was ist das Prinzip, es zu benutzen?

  3. Warum der Standard-Layout-Manager von JPanel funktioniert nicht, wenn ich das lösche 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);
        }
    }
}
} 
War es hilfreich?

Lösung

Vorschlag:

  • Nennen setVisible(true) nach Aufruf pack().Macht Sinn, nicht wahr?
  • Das BorderLayout weist das MyDrawPanel an, den p-Container zu füllen, da die Komponente standardmäßig hinzugefügt wird (dh BorderLayout.CENTER), und so funktioniert BorderLayout.
  • FlowLayout füllt den Container nicht, sondern lässt die Größe der Komponenten auf ihre bevorzugten Größen zu.
  • Mischen Sie Swing nicht mit AWT-Komponenten.dh verwenden Sie keine Panels, sondern JPanels .
  • requestFocus funktioniert nur bei fokussierbaren Komponenten, die angezeigt werden.
  • Verwenden Sie besser Tastenbelegungen als KeyListener.
  • Vermeiden Sie es nach Möglichkeit, die Größe von irgendetwas festzulegen.

Basierend auf Ihrem neuen Code liegt Ihr Problem daran, dass Sie anrufen setSize().Die meisten Layout-Manager respektieren dies nicht, sondern die bevorzugte Größe.Wenn Ihr Zeichnungs-JPanel so groß sein muss, dann machen Sie es so.Zum Beispiel versuchen:

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);
  }
}

Beachten Sie auch, dass Anforderungsfokus tun arbeiten, wenn das Bauteil fokussierbar ist:

  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();

Beachten Sie aber auch, dass KeyListener vermieden werden sollten.Verwenden Sie stattdessen Tastenbelegungen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top