2013-05-17 3 views
2

Хорошо, поэтому я делаю калькулятор, и я получаю ошибку переполнения стека, я предполагаю, потому что он пытается обрабатывать много данных.Ошибка переполнения стека с помощью GUI

import java.awt.*; 
import javax.swing.*; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

public class Size extends JPanel implements ActionListener { 

double base,size; 
int shoesize; 
String race; 

JButton calc = new JButton("Calculate"); 

JTextField textsize = new JTextField(20); 

public Size() { 
    //JButton calc; 
    System.out.println("Started the adding"); 

    calc.addActionListener(this); 
    textsize.addActionListener(this); 

    calc.setBounds(135, 200, 120, 40); 
    textsize.setBounds(15,40,70,20); 

    add(calc); 
    add(textsize); 

    setPreferredSize(new Dimension(400, 300)); 
    setLayout(null); 
} 

public static void main(String[] args) { 
    JFrame frame = new JFrame("Size calc"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.getContentPane().add(new Size()); 
    frame.pack(); 
    frame.setVisible(true); 
} 

@Override 
public void paint(Graphics g){ 
    DrawStats(g); 
} 

public void DrawStats(Graphics g) { 
    g.setFont(new Font(null, Font.PLAIN, 12)); 
    g.setColor(Color.red); 
    g.drawString("Aprrox Size: " + size, 135, 15); 
    paint(g); 
} 

public void actionPerformed(ActionEvent e) { 
    if (e.getSource() == calc) { 
     try { 
      String ShoeSize = textsize.getText(); 

      shoesize = Integer.parseInt(ShoeSize); 
      size = shoesize/2; 
     } catch (Exception j) { 
      System.out.println("Nothing inside of the text field"); 
     } 
    } 
    } 
} 

когда я закомментировать краски (г) я больше не получаю сообщение об ошибке:

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError 
at java.lang.Character.toLowerCase(Unknown Source) 
at java.lang.Character.toLowerCase(Unknown Source) 
at java.lang.String.toLowerCase(Unknown Source) 
at sun.font.SunFontManager.findFont2D(Unknown Source) 
at java.awt.Font.getFont2D(Unknown Source) 
at java.awt.Font.access$000(Unknown Source) 
at java.awt.Font$FontAccessImpl.getFont2D(Unknown Source) 
at sun.font.FontUtilities.getFont2D(Unknown Source) 
at sun.java2d.SunGraphics2D.checkFontInfo(Unknown Source) 
at sun.java2d.SunGraphics2D.getFontInfo(Unknown Source) 
at sun.java2d.pipe.GlyphListPipe.drawString(Unknown Source) 
at sun.java2d.SunGraphics2D.drawString(Unknown Source) 

Я хочу, чтобы обновить «размер Aproox» в режиме реального времени

ответ

5

Существует циклическая зависимость между paint и DrawStats — каждый называет другой. Не называйте краску напрямую. Скорее вызовите repaint. Также переопределить paintComponent, а не paint и вызвать super.paintComponent(g).

Удалить методы paint и DrawStats и заменить этим

@Override 
public void paintComponent(Graphics g) { 

    super.paintComponent(g)); 
    g.setFont(new Font("SansSerif", Font.PLAIN, 12)); 
    g.setColor(Color.red); 
    g.drawString("Aprrox Size: " + size, 135, 15); 
} 

Использовать Swing Timer для вызова repaint если требуются периодические перерисовки.

Кроме того: используйте соглашения об именах Java при именах имен имен, таких как drawStats.

+0

, как я могу это сделать? – user2393948

+1

@ user2393948 И не используйте 'null' LayoutManager. Всегда используйте соответствующий. –

+0

@ user2393948 Конечно, вы можете использовать 'Абсолютное позиционирование' (' null' LayoutManager), когда вы можете управлять им. – johnchen902

1

Ой ... Бесконечные рекурсии

@Override 
public void paint(Graphics g){ 
    DrawStats(g); // infinite recursion 
} 
public void DrawStats(Graphics g) { 
    g.setFont(new Font(null, Font.PLAIN, 12)); 
    g.setColor(Color.red); 
    g.drawString("Aprrox Size: " + size, 135, 15); 
    paint(g); // infinite recursion 
} 

Я полагаю, вы видите это в вашем трассировки стека:

... 
at Size.paint 
at Size.DrawStats 
at Size.paint 
at Size.DrawStats 
at Size.paint 
at Size.DrawStats 
(a lot more)... 

Удалить paint(g); в DrawStats

+0

Да, я понял, как мне его называть каждый раз, когда я нажимаю кнопку calc? Я попытался просто перейти к процедуре и сделать DrawStats (g); но он говорит, что «g» не может быть разрешено переменной. – user2393948

+0

@ user2393948 просто назовите 'repaint()'. Менеджер перерисовки в конечном итоге вызовет 'paintComponent' с соответствующим объектом« Graphics » –