Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Java ohjelma tökkii

Sivun loppuun

reidar [03.03.2004 23:58:41]

#

Nyt näyttää tältä. Miten saan tuon lukemaan noitten a:n ja b:n arvot noista kenttä1:sta ja kenttä2:sta. kenttä1.getInt() ei toimi.
JA miks se ei piirrä tuota uudelleen kun piste on lisätty vaan pitää suurentaa ikkuna ja sitt pienentää että entinen monikulmio häviää, vaikka tuolla on repaint.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Mon1 extends JFrame {
private Piirto paperi;
private JPanel pohja, kentät;
private Piirto piirtoalue;
private JTextField kenttä1,kenttä2;
private JButton lisääpiste;

public Mon1() {
super ("Monikulmio");
this.paperi = new Piirto();
//luodaan komponentit
kentät = new JPanel(new FlowLayout(FlowLayout.CENTER));
kenttä1 = new JTextField(5);
kenttä2 = new JTextField(5);
this.lisääpiste = new JButton("Lisää piste");
//liitetään komponentit paneeleihin
kentät.add(kenttä1);
kentät.add(kenttä2);
kentät.add(this.lisääpiste);

// liitetään tekstikenttiin ja painikkeeseen tapahtumankuuntelija
this.lisääpiste.addActionListener(new ActionListener() {


int a=5;
int b=5;
public void actionPerformed(ActionEvent tap) {
paperi.lisääPiste(a,b);
}
});
// otetaan selville ikkunaan liittyvä sisältöpaneeli
// ja liitetään komponentit siihen
Container sisaltopaneeli;
sisaltopaneeli = this.getContentPane();
sisaltopaneeli.setLayout(new BorderLayout());
sisaltopaneeli.add(this.paperi);
sisaltopaneeli.add(kentät, BorderLayout.SOUTH);
this.setSize(800, 600);

// lisätään ikkunankuuntelija, joka lopettaa ohjelman
// suorituksen, kun ikkuna suljetaan
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent sulkeutuminen) {
System.exit(0);
}
});
show();
}
class Piirto extends JPanel {
private int x;
private int y;
public void paintComponent(Graphics x) {
x.drawLine(30,10,30,485);
x.drawLine(0,450,800,450);
Polygon poly = new Polygon();
// polygoniin voidaan lisätä pisteitä tarvittaessa:
poly.addPoint( 30+20,450-30 );
poly.addPoint( 30+10,450-300 );
poly.addPoint( 30+100,450-350 );
poly.addPoint( 30+200,450-200 );
poly.addPoint( 30+250,450-50 );
poly.addPoint(30+this.x,450-this.y);
x.drawPolygon(poly);
}
// lisää uuden pisteen
public void lisääPiste(int uusix,int uusiy) {
this.x = uusix;
this.y = uusiy;
this.repaint();
}
}
}


Olenkohan edes oikeilla jäljillä kun tuntuu olevan nyt niin tuntematonto asiaa kuin olla voi.
Tehtävä oli siis:

Tee yksinkertainen piirto-ohjelma, jolla voi piirtää erivärisiä monikulmioita. Kukin monikulmio syötetään ohjelmaan yksi kulmapiste kerrallaan, eli kulman koordinaatit. Monikulmiossa voi olla mikä tahansa määrä kulmia. Monikulmion paikaksi määritellään sen ensimäiseksi syötetty kulmapiste joka esitetään selkeästi erottuvana. Jokaisella monikulmiolla on myös numero joka esitetään ensimmäisen kulmapisteen välittömässä läheisyydessä.
Lisäksi halutun väristä suorakulmiota voidaan siirtää ilmoittamalla sen uusi paikka( sen ensimmäisen kulmapisteen paikka)

Tee Luokka Monikulmio jonka yksittäinen ilmentymä (olio) kuvaa yhtä monikulmiota. Luokan konstrukstori saa parametrina monikulmion värin. Luokka sisältää metodit kulmapisteen lisäämiseksi ja monikulmion piirtämiseksi näyttöön. Lisäksi löytyy metodi monikulmion siirtämiseksi. Luokkaa ei tarvitse periä mistään aLibraryn luokasta (mutta voi halutessa tehdä niin).

Tee lisäksi erillinen pääohjelmaluokka.

Kiitos etukäteen

nikke [04.03.2004 00:59:30]

#

Tuosta syötteen lukemisesta... Mä oon aina tehnyt niin, että lukee halutussa kohteessa olevan merkkijonon, yrittää sen sitten muuttaa haluttuun muotoon (esim int tai vaikka double), näin saa kätevästi napattua kiinni mahdolliset virhesyötteet.
Esim. tähän tyyliin:

double luku = 0; //tai vaikka int luku...

try {
      luku = new Double(kenttä1.getText()).doubleValue();
      // ...luku = new Integer(----).intValue();
    }
    catch (Exception e) {
       kenttä1.setText("VIRHE!"); //Tai jotain muuta fiksua
     }

Ja siitä uudelleen piirtämisestä, joku varmasti osaa kertoa fiksummankin tavan, mutta yksi toimiva tapa, mikä nyt ensiksi tuli mieleen on, että laita sen this.repaint() rivin jälkeen seuraavat rivit:
this.setVisible(false);
this.setVisible(true);
Eli käyttää vaan paperia pois näkyvistä. Toimii kuin junan vessa... Mutta varmasti "oikeakin" tapa on olemassa. Tuohan on perusongelma liikettä mallinnettaessa.

Jep, toivottavasti oli edes jotain apua!!

Sami [04.03.2004 02:48:01]

#

Luvun hakeminen tekstikentästä käy esim. näin:

a = Integer.parseInt(kenttä1.getText());
b = Integer.parseInt(kenttä2.getText());

Jotta vanha monikulmio katoaisi uutta piirrettäessä, muuta koodiasi tällaiseksi (eli lisää yksi rivi):

public void paintComponent(Graphics x) {
x.clearRect(0, 0, this.getWidth(), this.getHeight());
x.drawLine(30, 10, 30, 485);

reidar [04.03.2004 13:52:37]

#

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

public class Mon1 extends JFrame {
    private Piirto paperi;
    private JPanel pohja, kentät;
    private Piirto piirtoalue;
    private JTextField kenttä1,kenttä2;
    private JButton lisääpiste;

    public Mon1() {
        super ("Monikulmio");
        this.paperi = new Piirto();
        //luodaan komponentit
        kentät = new JPanel(new FlowLayout(FlowLayout.CENTER));
        kenttä1 = new JTextField(5);
        kenttä2 = new JTextField(5);
        this.lisääpiste = new JButton("Lisää piste");
        //liitetään komponentit paneeleihin
        kentät.add(kenttä1);
        kentät.add(kenttä2);
        kentät.add(this.lisääpiste);

        // liitetään tekstikenttiin ja painikkeeseen tapahtumankuuntelija
        this.lisääpiste.addActionListener(new ActionListener() {
                int a,b;
            public void actionPerformed(ActionEvent tap) {


                try {
                a = new Double(kenttä1.getText()).intValue();
                // ...luku = new Integer(----).intValue();
                }
                catch (Exception e) {
                    kenttä1.setText("VIRHE!"); //Tai jotain muuta fiksua
                    }
                try {
                b = new Double(kenttä1.getText()).intValue();
                // ...luku = new Integer(----).intValue();
                }
                catch (Exception e) {
                    kenttä1.setText("VIRHE!"); //Tai jotain muuta fiksua
                    }
                   paperi.lisääPiste(a,b);
                   }
            });
         // otetaan selville ikkunaan liittyvä sisältöpaneeli
        // ja liitetään komponentit siihen
        Container sisaltopaneeli;
        sisaltopaneeli = this.getContentPane();
        sisaltopaneeli.setLayout(new BorderLayout());
        sisaltopaneeli.add(this.paperi);
        sisaltopaneeli.add(kentät, BorderLayout.SOUTH);
        this.setSize(800, 600);

         // lisätään ikkunankuuntelija, joka lopettaa ohjelman
         // suorituksen, kun ikkuna suljetaan
         this.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent sulkeutuminen) {
                    System.exit(0);
                }
            });
         show();
    }
class Piirto extends JPanel {
    private int x;
    private int y;
    public void paintComponent(Graphics x) {

        x.drawLine(30,10,30,485);
        x.drawLine(0,450,800,450);
        Polygon poly = new Polygon();
        // polygoniin voidaan lisätä pisteitä tarvittaessa:
        poly.addPoint( 30+20,450-30 );
        poly.addPoint( 30+10,450-300 );
        poly.addPoint( 30+100,450-350 );
        poly.addPoint( 30+200,450-200 );
        poly.addPoint( 30+250,450-50 );
        poly.addPoint(30+this.x,450-this.y);
        x.drawPolygon(poly);
        }
    // lisää uuden pisteen
    public void lisääPiste(int uusix,int uusiy) {
        this.x = uusix;
        this.y = uusiy;
        this.repaint();


    }
}
}

Nyt käy niin että se vaihtaa vaan tuon yhen pisteen paikkaa kun lisää pisteen eli sen entisen pisteen pitäs kanssa jäädä voimaan

Sami [04.03.2004 18:10:05]

#

Bugi on siinä, että se luo joka piirtokerralla uuden Polygon-olion. Koodia pitäisi muuttaa siten, että luokassa Piirto olevaa riviä 'Polygon poly = new Polygon();' pitäisi siirtää muutama rivi ylöspäin (paintComponent-metodin ulkopuolelle)


Oli aika paljonkin korjattavaa (ja vielä on joitakin kohtia, mitkä tekisin itse toisin), mutta tässä on ainakin jotenkin kuvailujesi mukaan toimiva koodi.
Muutetut kohdat merkitsin tällaisella: //!!!!!

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

public class Mon1 extends JFrame {
	private Piirto paperi;
	private JPanel pohja, kentät;
	private Piirto piirtoalue;
	private JTextField kenttä1, kenttä2;
	private JButton lisääpiste;

	public Harj4() {
		super("Monikulmio");
		this.paperi = new Piirto();
		//luodaan komponentit
		kentät = new JPanel(new FlowLayout(FlowLayout.CENTER));
		kenttä1 = new JTextField(5);
		kenttä2 = new JTextField(5);
		this.lisääpiste = new JButton("Lisää piste");
		//liitetään komponentit paneeleihin
		kentät.add(kenttä1);
		kentät.add(kenttä2);
		kentät.add(this.lisääpiste);

		// liitetään tekstikenttiin ja painikkeeseen tapahtumankuuntelija
		this.lisääpiste.addActionListener(new ActionListener() {
			int a, b;
			public void actionPerformed(ActionEvent tap) {

				try {
					a = new Double(kenttä1.getText()).intValue();
					// ...luku = new Integer(----).intValue();
				} catch (Exception e) {
					kenttä1.setText("VIRHE!"); //Tai jotain muuta fiksua
				}
				try {
					b = new Double(kenttä2.getText()).intValue(); //!!!!! kenttä1 muutettu kenttä2:ksi
					// ...luku = new Integer(----).intValue();
				} catch (Exception e) {
					kenttä1.setText("VIRHE!"); //Tai jotain muuta fiksua
				}
				paperi.lisääPiste(a, b);
			}
		});
		// otetaan selville ikkunaan liittyvä sisältöpaneeli
		// ja liitetään komponentit siihen
		Container sisaltopaneeli;
		sisaltopaneeli = this.getContentPane();
		sisaltopaneeli.setLayout(new BorderLayout());
		sisaltopaneeli.add(this.paperi);
		sisaltopaneeli.add(kentät, BorderLayout.SOUTH);
		this.setSize(800, 600);

		// lisätään ikkunankuuntelija, joka lopettaa ohjelman
		// suorituksen, kun ikkuna suljetaan
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent sulkeutuminen) {
				System.exit(0);
			}
		});
		show();
	}
	class Piirto extends JPanel {
		private int x;
		private int y;
		private Polygon poly; //!!!!! Olion attribuutti, jotta vanhatkin laitetut tiedot säilyy

		// "alustetaan" monikulmio
		//!!!!! Lisätty muodostin
		public Piirto() {
			this.poly = new Polygon();
			this.poly.addPoint(30 + 20, 450 - 30);
			this.poly.addPoint(30 + 10, 450 - 300);
			this.poly.addPoint(30 + 100, 450 - 350);
			this.poly.addPoint(30 + 200, 450 - 200);
			this.poly.addPoint(30 + 250, 450 - 50);
		}

		//!!!!! Siirretty monikulmion alkupisteet muodostimeen
		public void paintComponent(Graphics x) {
			x.clearRect(0, 0, this.getWidth(), this.getHeight());  //!!!!! Tyhjentää ruudun
			x.drawLine(30, 10, 30, 485);
			x.drawLine(0, 450, 800, 450);
			// polygoniin voidaan lisätä pisteitä tarvittaessa:
			poly.addPoint(30 + this.x, 450 - this.y);
			x.drawPolygon(poly);
		}
		// lisää uuden pisteen
		public void lisääPiste(int uusix, int uusiy) {
			this.x = uusix;
			this.y = uusiy;
			this.repaint();

		}
	}
}

reidar [04.03.2004 20:31:32]

#

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

public class Mon1 extends JFrame {
    private Piirto paperi;
    private JPanel pohja, kentät;
    private Piirto piirtoalue;
    private JTextField kenttä1, kenttä2;
    private JButton lisääpiste;

    public Mon1() {
        super("Monikulmio");
        this.paperi = new Piirto();
        //luodaan komponentit
        kentät = new JPanel(new FlowLayout(FlowLayout.CENTER));
        kentät.setBackground(Color.white);
        kenttä1 = new JTextField(5);
        kenttä2 = new JTextField(5);
        this.lisääpiste = new JButton("Lisää piste");
        //liitetään komponentit paneeleihin
        kentät.add(kenttä1);
        kentät.add(kenttä2);
        kentät.add(this.lisääpiste);

        // liitetään tekstikenttiin ja painikkeeseen tapahtumankuuntelija
        this.lisääpiste.addActionListener(new ActionListener() {
            int a, b;
            public void actionPerformed(ActionEvent tap) {

                try {
                    a = new Double(kenttä1.getText()).intValue();
                    // ...luku = new Integer(----).intValue();
                } catch (Exception e) {
                    kenttä1.setText("VIRHE!"); //Tai jotain muuta fiksua
                }
                try {
                    b = new Double(kenttä2.getText()).intValue();
                    // ...luku = new Integer(----).intValue();
                } catch (Exception e) {
                    kenttä2.setText("VIRHE!"); //Tai jotain muuta fiksua
                }
                paperi.lisääPiste(a, b);
            }
        });
        // otetaan selville ikkunaan liittyvä sisältöpaneeli
        // ja liitetään komponentit siihen
        Container sisaltopaneeli;
        sisaltopaneeli = this.getContentPane();
        sisaltopaneeli.setLayout(new BorderLayout());
        sisaltopaneeli.add(this.paperi);
        sisaltopaneeli.add(kentät, BorderLayout.SOUTH);
        this.setSize(800, 600);

        // lisätään ikkunankuuntelija, joka lopettaa ohjelman
        // suorituksen, kun ikkuna suljetaan
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent sulkeutuminen) {
                System.exit(0);
            }
        });
        show();
    }
    class Piirto extends JPanel {
        private int x;
        private int y;
        private Polygon poly;

        public Piirto () {
            poly = new Polygon();
        }
        public void paintComponent(Graphics x) {
            x.clearRect(0, 0, this.getWidth(), this.getHeight());
            x.drawLine(30, 10, 30, 485);
            x.drawLine(0, 450, 800, 450);
            // polygoniin voidaan lisätä pisteitä tarvittaessa:

            x.fillPolygon(poly);
        }
        // lisää uuden pisteen
        public void lisääPiste(int uusix, int uusiy) {

            this.x = uusix;
            this.y = uusiy;
            poly.addPoint(30 + this.x, 450 - this.y);
            this.repaint();

        }
    }
}

nyt toimii kitos siitä.
mitenköhän saa sitte että tuohon samaan ikkunaan voi piirtää monta eri monikulmiota ja että eka piste olis niissä korostettu ja sen vieressä numero joka kertoo monesko kuvio se on

Sami [04.03.2004 22:03:20]

#

koodia en nyt ala tekemään, mutta perusideanahan on tehdä useita Polygon-olioita ja piirtää ne kaikki. Oliot kannattaa laittaa joko taulukkoon (jos niitä voi olla vain rajallinen määrä) tai vektoriin (jos monikulmioita voi olla rajaton määrä).
Ensimmäisen pisteen korostaminen onnistuu ainakin laittamalla ensimmäinen pisteet muistiin ja piirtämällä se esim. punaisella värillä. Tekstin kirjoittaminenkin sen viereen käy todella helposti ja monikulmion numero on suoraan se, missä taulukon (tai vektorin) alkiossa monikulmio on.


P.S. toivottavasti saat tuosta jotain selvää :)

reidar [08.03.2004 12:58:55]

#

mites saa esim nappiin toiminnon että aloittaa uutta monikulmiota piirtämään ?

reidar [09.03.2004 20:00:24]

#

Mitenkä sen ekan pisteen saa muistiin ?


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta