2009-12-02 23 views
5

Estoy buscando la descripción más básica de cómo dibujar texto dentro de un JPanel. Sé que hay mil millones de tutoriales por ahí, pero ninguno de ellos está haciendo clic conmigo y tengo algunas preguntas específicas que pueden ayudar a otros que están confundidos. Como configuración (una aplicación de prueba) tengo una sola clase que tiene un JLabel, un JTextField, un JButton y un JPanel. La aplicación lee entradas de un archivo externo y debe mostrar su promedio en el panel cuando se presiona JButton. Tengo toda la programación subyacente resuelta (es decir, el botón responde e imprime el promedio en la línea de comandos), pero parece que no puedo resolver cómo imprimir el promedio en el panel. Supongo que mi mayor pregunta es cómo incorporar el método paint() o paintComponet() junto con el resto del código. ¿Debería ser su propia clase? ¿El JPanel debería ser su propia clase? Parece que eso es lo que la mayoría de los tutoriales me dicen, no estoy seguro de cuál es exactamente el primer paso. El código se ve así:dibujo de texto dentro de un JPanel

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.io.*; 

public class Main extends JFrame implements ActionListener { 
    private int[] intArray = new int[10000]; 
    private int numOfInts = 0; 
    private int avg = 0; 

    protected JButton avgBtn; 
    protected JTextField indexEntry; 
    protected JLabel instructions; 
    protected JPanel resultsPanel; 

    public Main(){ 

    //create main frame 
    this.setTitle("Section V, question 2"); 
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    this.setSize(350, 250); 
    this.setLayout(new GridLayout(4, 1)); 

    //create instruction label and add to frame 
    instructions = new JLabel("Follow the instructions on the exam to use this program"); 
    this.add(instructions); 

    //create textfield for index entry and add to frame 
    indexEntry = new JTextField(); 
    this.add(indexEntry); 

    //create button for average and add to frame 
    avgBtn = new JButton("Click for Average"); 
    this.add(avgBtn); 
    avgBtn.addActionListener(this); 

    //create panel to display results and add to frame 
    resultsPanel = new JPanel(); 
    resultsPanel.setBackground(Color.BLUE); 
    this.add(resultsPanel); 

    //read in from file 
    readFromFile(); 

    //compute average 
    computeAverage(); 
    } 

    private void readFromFile() { 
    try { 
      // Open the file 
      FileInputStream fstream = new FileInputStream("numbers.dat"); 
      BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); 

      //create placeholder for read in ints 
      String strLine; 

      //Read File Line By Line 
      int i = 0; 
      while ((strLine = br.readLine()) != null) { 
       //place ints in array and increament the count of ints 
       System.out.println (strLine); 
       intArray[i] = Integer.parseInt(strLine); 
       numOfInts++; 
       i++; 
      } 
      //Close the input stream 
      in.close(); 
      System.out.println ("numOfInts = " + numOfInts); 
    } 
    catch (Exception e) { 
      //Catch exception if any 
      System.err.println("Error: " + e.getMessage()); 
    } 
    } 

    //compute averaage 
    private void computeAverage() { 
    int sum = 0; 
    for (int i = 0; i < numOfInts; i++) 
    sum += intArray[i]; 
    avg = sum/numOfInts; 
    System.out.println("avg = " + avg); 
    } 

//event handling 
public void actionPerformed(ActionEvent e) { 
    if(e.getSource() == avgBtn) { 
      computeAverage(); 
    } 
} 

//"main" function 
public static void main(String[] args) { 
    Main m = new Main(); 
    m.setVisible(true); 
} 

//paint 
public void paintComponent(Graphics g){ 
    g.drawString(avg, 75, 75); 
} 
} 

Se agradece cualquier ayuda/dirección. Sé que he usado este código recientemente para otras preguntas, ¡solo quiero saberlo todo! Lo ideal sería que el panel muestre el promedio de las entradas de lectura cuando se hizo clic en el botón y que se muestre lo que se ingresó en el campo de texto cuando se enfocó y se presionó ingresar, pero estoy dando pequeños pasos, y como dije, Me gustaría que este hilo sea un tutorial general para otras personas con preguntas similares que no encuentran respuestas de doctores u otros sitios. Muchas gracias de antemano. Dan :)

Respuesta

6

Crear una clase interna que se extiende JPanel dentro de su clase principal:

class MyPanel extends JPanel { 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawString(Integer.toString(avg), 75, 75); 
    } 

} 

Luego hay que llamar a volver a pintar en ese panel después de llamar computeAverage() en actionPerformed:

//event handling 
public void actionPerformed(ActionEvent e) { 
    if (e.getSource() == avgBtn) { 
     computeAverage(); 
     panel.repaint(); 
    } 
} 
+0

Gracias por el trabajo que pones en tu respuesta. Aceptado por sí solo ... – danwoods

+1

-1 la sugerencia de cambiar el método paintComponent() para pintar() es incorrecta. Anular pintura() en el nivel de marco es una de las peores cosas que puedes hacer cuando no invocas super.paint(). Por un lado, ninguno de los componentes agregados al marco será pintado, ya que esto es manejado por la súper clase. También perderá optimizaciones de pintura. – camickr

+0

tienes razón, arreglé la solución –

7

Agregue un JLabel al JPanel.

Llamar setText (String) en JLabel y su texto se dibujará en el JPanel.

+0

Me encanta la simplicidad de esto. No es exactamente lo que estaba buscando. pero gracias por mirar mi pregunta. – danwoods

2

1) Un JFrame no tiene un método paintComponent() por lo que el código que publicaste no hará nada. Necesita crear un JPanel personalizado y anular su método paintComponent() para hacer su pintura personalizada.

2) Incluso si hace lo anterior, la pintura no se mostrará porque un panel tiene un tamaño cero por defecto. Por lo tanto, deberá establecer el tamaño preferido del panel para asegurarse de que esté visible.

3) ¿Por qué estás haciendo esto? Todo lo que necesita hacer es usar un JLabel y establecer el texto de JLabel.

Me cuesta creer que haya mirado otros tutoriales. El tutorial de Swing en Custom Painting tiene un programa de 20 líneas que muestra los conceptos básicos.

+0

Guau, un poco abrasivo ¿eh? Puede que desee cambiar su nombre de pantalla a camdickr. Gracias por el enlace. – danwoods

+1

Excepto que proporcioné la respuesta correcta. El que usted aceptó fue editado después de que se publicó el mío. También sugerí el JLabel antes del otro cartel. Proporcioné explicaciones de por qué el código no funcionaba y le di sugerencias para solucionarlo. "Dale a alguien un pescado que coma por un día. Enseña a alguien a pescar y luego come de por vida. Te di herramientas y consejos para aprender a desarrollar tu propia habilidad, que será mejor a largo plazo. Por eso no lo hago. código postal. Esperar que la gente escriba código para usted es la actitud incorrecta. – camickr

-1

Creo que no debería estar subclasificando JFrame. Cree una instancia de JFrame como instancia
variable de la clase Principal y añádale el JPanel, etc.

+0

esto ni siquiera intenta responder a la pregunta, sería mejor como un comentario sobre la pregunta. – pstanton

+0

Estoy de acuerdo. Quise agregar rápidamente algo que pensé que ayudaría Pero mirando hacia atrás, estoy de acuerdo en que mi publicación no proporciona mucha ayuda. – sateesh

+0

, solo publique un comentario, sigue siendo útil, pero no se presenta como una respuesta. – pstanton

Cuestiones relacionadas