problem z paintComponent

0

Otóż chciałbym aby w głównym oknie można było kontrolować wymiary elipsy którą kreśli program. Wydaje mi się , że kod napisałem dobrze, kompiluje się a jednak podczas uruchamiania jest zawiecha. Wie ktoś co może być przyczyną ?

import javax.swing.*;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.*;
import java.awt.*;
import java.awt.Image;
import java.io.IOException;
import java.io.*;
import java.util.*;

public class Kep implements Runnable, ActionListener {

    public JMenuItem zapiszMenuItem, exitMenuItem;
    public JButton start;
    public JTextArea textArea;
   	public int sx,sy;
	public JMenuItem ziemia,mars,jowisz,saturn,uran,neptun;
	public JPanel panel;
    public static void main(String args[]){
	
        SwingUtilities.invokeLater(new Kep() ); //metoda run()
    }




    //okno i inne
    public void run(){ //z interfejsu Runnable
        JFrame okno = new JFrame("Program ilustrujący II prawo Keplera");
        
        okno.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        okno.setLayout(new BorderLayout());
        //tworzenie menu
        JMenuBar menuBar = new JMenuBar();
        JMenu plikMenu = new JMenu("Plik");
        plikMenu.setMnemonic(KeyEvent.VK_P);
        menuBar.add(plikMenu);
        //opcja zapisz
        zapiszMenuItem=new JMenuItem("Zapisz",KeyEvent.VK_Z);
        zapiszMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, ActionEvent.CTRL_MASK));
        zapiszMenuItem.addActionListener(this);
        plikMenu.add(zapiszMenuItem);
        //opcja exit
        exitMenuItem=new JMenuItem("Wyjscie",KeyEvent.VK_X);
        exitMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,ActionEvent.ALT_MASK | ActionEvent.CTRL_MASK));
        exitMenuItem.addActionListener(this);
        plikMenu.add(exitMenuItem);
        //dodanie menu
        menuBar.add(plikMenu);
		//wybór planety o określonej odległości od Słońca
        JMenu wybor = new JMenu("Wybierz planetę");
        wybor.setMnemonic(KeyEvent.VK_W);	
        menuBar.add(wybor);
        //ziemia
        ziemia=new JMenuItem("Ziemia",KeyEvent.VK_E);
        ziemia.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_E, ActionEvent.CTRL_MASK));
        ziemia.addActionListener(this);
        wybor.add(ziemia);
        //mars
        mars=new JMenuItem("Mars",KeyEvent.VK_M);
        mars.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_M, ActionEvent.CTRL_MASK));
        mars.addActionListener(this);
        wybor.add(mars);
        //jowisz
        jowisz=new JMenuItem("Jowisz",KeyEvent.VK_J);
        jowisz.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_J, ActionEvent.CTRL_MASK));
        jowisz.addActionListener(this);
        wybor.add(jowisz);
        //saturn
        saturn=new JMenuItem("Saturn",KeyEvent.VK_S);
        saturn.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_S, ActionEvent.CTRL_MASK));
        saturn.addActionListener(this);
        wybor.add(saturn);
        //uran
        uran=new JMenuItem("Uran",KeyEvent.VK_U);
        uran.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_U, ActionEvent.CTRL_MASK));
        uran.addActionListener(this);
        wybor.add(uran);
        //neptun
        neptun=new JMenuItem("Neptun",KeyEvent.VK_N);
        neptun.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_N, ActionEvent.CTRL_MASK));
        neptun.addActionListener(this);
        wybor.add(neptun);        
        //koniec dodawania planet
        //przycisk startowy animacji
        start = new JButton("Start");
        //start.setPrefferedSize();
        start.addActionListener(this);


       //tekst w oknie
		JTextArea textArea = new JTextArea(5, 20);
		JScrollPane scrollPane = new JScrollPane(textArea);
		textArea.setEditable(false);
		textArea.append("Prezentacja II Prawa Keplera");
		textArea.append("\n\n Promień wodzący poprowadzony ze środka Słońca do środka planety zakreśla równe pola powierzchni w równych odstępach czasu.");
	   //kontener na grafike
	    panel = new graf( Color.yellow ,45,154);

	   //
	   	okno.setJMenuBar(menuBar);
	    okno.getContentPane().add(panel,BorderLayout.CENTER);
		okno.getContentPane().add(start,BorderLayout.SOUTH);
		okno.getContentPane().add(textArea,BorderLayout.NORTH);


        //pokazanie okna\
        okno.pack();
        okno.setSize(800,800);
        okno.setVisible(true);

    }
    //obsluga zdarzen

    public void actionPerformed(ActionEvent e){//z niterfejsu ActionListener
        Object source=e.getSource();

        if(source == ziemia){
            sx=45;sy=154;panel = new graf( Color.yellow ,sx,sy);}
        else if (source == mars){
            sx=50;sy=154;panel = new graf( Color.yellow ,sx,sy);}
        else if (source == jowisz){
            sx=55;sy=154;panel = new graf( Color.yellow ,sx,sy);}
        else if (source == saturn){
            sx=55;sy=154;panel = new graf( Color.yellow ,sx,sy);} 
        else if (source == uran){
            sx=60;sy=154;panel = new graf( Color.yellow ,sx,sy);}  
        else if (source == neptun){
            sx=65;sy=154;panel = new graf( Color.yellow ,sx,sy);}            
        else if(source ==start){
        	
        	}
    }
}
class graf extends JPanel

{
  public int ux,uy;
  public graf(Color kol,int ux,int uy) 
    {
        setForeground(kol);
    }
	
	
 public void slonce (Graphics g,int x,int y)
{
	g.setColor( Color.yellow);
	g.fillOval(x-10,y+6,20,20);
	
}
public void piksel (Graphics g,int x,int y,int c)
{
	if (c==0) g.setColor( Color.black );
	else g.setColor ( Color.blue );
	
	g.drawLine(x,y,x+1,y);
}
    public void elipsa (Graphics g,int xs,int ys,int rx,int ry)
{
// na podstawie algorytmu kreslenia elipsy Bresenhama
int x,y; //współrzędne punktów na obwodzie elipsy o środku w początku układu współrzędnych
int e,e1,e2; ////wyrażenie błędu dla narysowanego punktu P
int rx2 = rx * rx;
int ry2 = ry * ry;
int kolor=0;
// zaczynamy
x=0;y=ry;
e=0;
int fx=0; 
int fy=rx;
while (ry2*x<=rx2*y) //pierwsza petla
{
//zmienimy kolory
if (kolor==0) kolor=1;
else kolor=0;
piksel(g,x+xs,y+ys,kolor); //prawy dolny 
piksel(g,x+xs,ys-y,kolor); //prawy gorny
piksel(g,xs-x,y+ys,kolor); //lewy dolny
piksel(g,xs-x,ys-y,kolor);//lewy gorny

e1=e+2*ry2*x+ry2;
e2=e1-2*rx2*y+rx2;
x++;
if ((e1+e2)<0) e=e1;
else 
{
e=e2;
y--;
} // koniec petli
while(y>=0)//poczatek petli
{
if (kolor==0) kolor=1;
else kolor=0;	
piksel(g,x+xs,y+ys,kolor); //prawy dolny
piksel(g,x+xs,ys-y,kolor); //prawy gorny
piksel(g,xs-x,y+ys,kolor); //lewy dolny
piksel(g,xs-x,ys-y,kolor);//lewy gorny

e1=e-2*rx2*y+rx2;
e2=e1+2*ry2*x+ry2;
y--;
if((e1+e2)>=0) e=e1;
else 
{
e=e2;
x++;
}

}//koniec petli

}
// teraz narysuje slonce
slonce(g,xs,ry);

}


    public void paintComponent (Graphics g)
    {
    	elipsa(g,300,300,ux,uy);
    	//
    }
}
0

Nie chciałbym, żeby to wyszło bardzo obcesowo, ale najlepiej będzie to wiedział Twój debugger. :)
Przede wszystkim, żeby upewnić się, że dobrze zaimplementowałeś elipsę użyj zamiast swojego kodu elipsy metodę dostępną w AWT. Jeżeli będzie się rysować w miarę dobrze, to winna będzie właśnie Twoja implementacja. Jeżeli będzie mimo to się zawieszać, to błąd jest gdzieś w pozostałym kodzie, co powinieneś debugerem szybko wyhaczyć.
Co do elipsy, to kiedyś popełniłem w C identyczną rzecz i od razu Ci powiem, że wszystkie mnożenia przez 2 oraz wielokrotność 2 należy pozamieniać na przesunięcie w lewo, np. 2 * x należy zmienić na x << 1, a dzielenia na przesunięcia w prawo. Przesunięcie bitowe jest o prawie rząd wielkości krótsze od mnożenia, a tym bardziej od super czasochłonnego dzielenia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1