2016-07-10 9 views
1

ich einige Probleme mit den folgenden Klassen: Mein Problem ist, dass der JPanel nicht auf dem JFrame gerendert wird:JPanel ist nicht showen

MainFrame.class

import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class MainFrame extends JFrame { 

    JPanel panel; 

    public MainFrame() { 
     setTitle("TestFrame"); 
     setLayout(null); 
     setSize(800, 450); 
     setLocation(400, 225); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

     panel = new TestPanel(); 
     getContentPane().add(panel); 
     panel.setLocation(0, 0); 
     panel.setSize(64, 64); 
     panel.setVisible(true); 

     setLocationRelativeTo(null); 
     setVisible(true); 
    } 

    public void start() { 
     while(true) { 
      panel.repaint(); 

      try { 
       Thread.sleep(20); 
      } catch(InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     MainFrame frame = new MainFrame(); 
     frame.start(); 
     System.exit(-1); 
    } 
} 

TestPanel.class

import java.awt.Color; 
import java.awt.Graphics; 

import javax.swing.JPanel; 

public class TestPanel extends JPanel { 

    public TestPanel() { 
    } 

    @Override 
    public void paintComponents(Graphics g) { 
     super.paintComponent(g); 

     g.setColor(Color.BLUE); 
     g.drawString("Test", 0, 0); 
    } 
} 

Irgendwelche Ideen, die mit diesem Code falsch sind? Ps. Ich bin Deutscher - Entschuldigung für mein Englisch!

+0

Zuerst fügen wir das Panel wie folgt hinzu: getContentPane(). add (panel); können Sie es einfach mit der .add() -Methode hinzufügen. Zweitens, mit dem Intellij Debugger können Sie sehen, dass die Startmethode nicht richtig funktioniert. Warum haben Sie eine Startmethode, die alle 20 Sekunden ein neues Panel anzeigt? – Aris

Antwort

2

Sie haben die paintComponents Methode statt paintComponent (ohne "s") außer Kraft gesetzt.

Ihre Endlosschleife while(true) blockiert den EDT-Thread, der die GUI einfrieren wird. Sie müssen das auf einem neuen Thread ausführen oder eine bessere Lösung wird sein, ein javax.swing.Timer zu verwenden, um das Panel zu aktualisieren.

Auch, wie @CoderinoJavarino erwähnt hat, müssen Sie die y Koordinate im drawString(....) Aufruf auf einen größeren Wert setzen.

Wie es in der Dokumentation erwähnt:

Die Basislinie des äußersten linken Zeichen an der Position (x, y)

Sie können etwas tun sicher, den Text isn zu machen 't drawn offscreen:

g.drawString("Test", 0, g.getFontMetrics().getHeight()); 
+0

Okay, das hilft sehr, ich habe noch nicht wirklich viel mit Swing gemacht. Vielen Dank :) – Maanex

2

Sie sehen nicht die Zeichenfolge, weil Ihre y Parameter zu klein sind - es definiert, wo der Boden des String ist, und da der tiefste Punkt der Saite an ganz oben ist, kann man es nicht sehen.

package test; 

import java.awt.Color; 
import java.awt.Graphics; 

import javax.swing.*; 

public class TestPanel extends JPanel{ 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.setColor(Color.blue); 
     g.drawString("Hello", 0, 10); 
    } 

    public static void main (String[] args) { 

     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new TestPanel()); 
     frame.setSize(100, 100); 
     frame.setVisible(true); 

    } 

} 

Auch ich mag es wirklich nicht Ihre start Methode, auch wenn Sie es noch nicht verwenden. Was Sie wahrscheinlich tun möchten, ist das Panel implementieren ActionListener, und irgendwo in Ihrem Initialisierungscode einen Timer erstellen - Timer t = new Timer (delay, this); t.setRepeats(true); t.start();. Dadurch wird ein neuer Thread erstellt, der actionPerformed Methode alle delay Millisekunden aufrufen wird.

package test; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.*; 

public class TestPanel extends JPanel implements ActionListener{ 

    private int red = 0; 
    private Timer t; 

    TestPanel() { 
     t = new Timer(20, this); 
     t.setRepeats(true); 
     t.start(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.setColor(new Color (red, 0, 0)); 
     g.drawString("Hello", 0, 10); 

    } 

    public static void main (String[] args) { 

     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new TestPanel()); 
     frame.setSize(100, 100); 
     frame.setVisible(true); 

    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     red = (red + 2) % 255; 
     repaint(); 
    } 

} 
+0

Ich habe den Timer bereits in einigen anderen Projekten benutzt, aber ich habe nicht darüber nachgedacht ihn in dieser Situation zu benutzen, danke :) – Maanex