import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; /** * Luokka Ikkuna, joka periytyy luokasta JFrame. Piirtää graafisen * käyttöliittymän perusosat paikoilleen. Luokassa määritellään * menuvalikon toiminta ja luodaan uusi lasku metodilla, joka * päivittää Laskupaneelin (tarvittaessa), Vastauspaneelin ja * Ötökkäpaneelin. Luokka sisältää päämetodin, josta koko * ohjelma ajetaan. * * @author Karoliina Tiuraniemi * @version 1.0, 18.1.2009 */ public class Ikkuna extends JFrame { private static final long serialVersionUID = 1L; private Otokkapaneeli otokkapaneeli; private Laskupaneeli laskupaneeli; private Vastauspaneeli vastauspaneeli; private JLabel label; private Peli peli; private Matikka matikka; /** * Konstruktori, joka piirtää ensin alkudialogin ja sitten ohjelman pääikkunan. * Metodi myös kutsuu uusiLasku() metodia. */ public Ikkuna() { // kysytään ensin alkudialogissa kumpaa tasoa pelataan. Alkudialogi alkudialogi = new Alkudialogi(this, true); alkudialogi.setVisible(true); int taso = alkudialogi.annaSyotettyTaso(); this.peli = new Peli(taso, 5); this.matikka = this.peli.annaMatikka(); Alapaneeli alapaneeli = new Alapaneeli(); // lisätään alapaneeli alas this.add(BorderLayout.SOUTH, alapaneeli); alapaneeli.setBorder(BorderFactory.createLineBorder(Color.BLACK)); this.label = new JLabel("Peli alkaa."); alapaneeli.add(label); // metodi, joka piirtää muut paneelit. this.uusiLasku(); // luo menupalkin JMenuBar menuBar = new JMenuBar(); // luo menun ja lisää sen menupalkkiin JMenu menu = new JMenu("Peli"); menuBar.add(menu); // luo ja lisää menuun itemeita JMenuItem aloita = new JMenuItem("Aloita alusta"); aloita.addActionListener(new AloitaListener()); menu.add(aloita); menu.addSeparator(); JMenuItem vaihda = new JMenuItem("Vaihda taso..."); // lisää uuden tapahtumakuuntelijan menun itemille vaihda.addActionListener(new VaihdaListener()); menu.add(vaihda); JMenuItem asetukset = new JMenuItem("Asetukset..."); asetukset.addActionListener(new AsetusListener()); menu.add(asetukset); menu.addSeparator(); JMenuItem lopeta = new JMenuItem("Lopeta"); // lisää uuden tapahtumakuuntelijan menun itemille lopeta.addActionListener(new LopetaListener()); menu.add(lopeta); // määrittelee menubarin tämän jframen menubariksi this.setJMenuBar(menuBar); // muutetaan framen koko sellaiseksi, että se ottaa huomioon // toivotut koot this.pack(); // ikkunan otsikko this.setTitle("Ötökkämatikka"); // avaa ikkunan keskeltä this.setLocationRelativeTo(null); // sulkee ohjelman, kun ikkuna suljetaan this.setDefaultCloseOperation(EXIT_ON_CLOSE); // määrittelee ikkunan näkyväksi this.setVisible(true); } /** * Sisäluokka Alapaneeli, joka periytyy luokasta JPanel. * Piirtää Ikkunan alapaneeliin liukuvärjäyksen. * @author Karoliina Tiuraniemi * */ public class Alapaneeli extends JPanel { private static final long serialVersionUID = 1L; /** * Metodi, joka piirtää alapaneelin grafiikan eli * liukuvärjäyksen vihreästä mustaan. Siitä jää näkyviin * noin puolet. * @param g grafiikkaolio */ public void paintComponent(Graphics g) { // graphics olio tyyppimuunnetaan graphics 2D:ksi Graphics2D g2 = (Graphics2D) g; //määritellään liukuvärin värit ja koordinaatit int leveys = this.getWidth(); int korkeus = this.getHeight(); int suuriLeveys = (int) Math.round(leveys * 2); g2.setPaint(new GradientPaint(0, 0, Varit.VIHREA, suuriLeveys, 0, Color.BLACK, false)); // määritellään neliö, jonka sisälle värjäys tulee Rectangle r = new Rectangle(0,0,leveys,korkeus); // kutsutaan graphic-oliota, joka täyttää neliön. g2.fill(r); } } /** * Metodi, joka vaihtaa alapaneelin tekstin * @param teksti */ public void vaihdaAlapaneelinTeksti(String teksti){ this.label.setText(teksti); } /** * Metodi, joka antaa ötökkäpaneelin * @return this.otokkapaneeli */ public Otokkapaneeli annaOtokkapaneeli(){ return this.otokkapaneeli; } /** * Metodi, joka antaa pelin * @return this.peli */ public Peli annaPeli(){ return this.peli; } /** * Metodi, joka asettaa pelin * @param peli */ public void asetaPeli(Peli peli){ this.peli = peli; } /** * Metodi, joka asettaa Ikkunaan laskuissa käytettävän matikka-olion. * @param matikka */ public void asetaMatikka(Matikka matikka){ this.matikka = matikka; } /** * Metodi, joka näyttää uuden laskun eli piirtää uuden laskupaneelin, * vastauspaneelin ja keskipaneelin. */ public void uusiLasku(){ // jos peli on käynnissä if (!this.peli.peliLoppui()){ System.out.println(""); System.out.println("Pelataan vuoro " + (this.peli.annaVuorolaskuri() + 1)); this.vaihdaAlapaneelinTeksti("Pelataan vuoro " + (this.peli.annaVuorolaskuri() + 1) + "/" + this.peli.annaVuoromaksimi()); System.out.println(this.peli.annaTaso()); // 1. käsitellään laskupaneeli ainoastaan tasolla 2 if (this.peli.annaTaso() == 2){ // jos laskupaneeli on olemassa if (this.laskupaneeli != null){ // poistetaan vanha paneeli näkyvistä this.remove(this.laskupaneeli); } // lisätään uusi laskupaneeli ikkunaan this.laskupaneeli = new Laskupaneeli(this.matikka); this.add(BorderLayout.NORTH, this.laskupaneeli); // määritellään sille haluttu koko Dimension laskukoko = new Dimension(600, 100); this.laskupaneeli.setPreferredSize(laskukoko); // piirretään laskupaneeli metodilla, // joka arpoo samalla tehtävän this.laskupaneeli.piirra(); } else if (this.peli.annaTaso() == 1){ // tason 1 tehtävä arvotaan tässä this.matikka.arvoMontako(); } // 2. käsitellään vastauspaneeli // jos vastauspaneeli on olemassa if (this.vastauspaneeli != null){ // poistetaan vanha paneeli näkyvistä this.remove(this.vastauspaneeli); } // lisätään uusi vastauspaneeli ikkunaan this.vastauspaneeli = new Vastauspaneeli(this.matikka, this); this.add(BorderLayout.EAST, this.vastauspaneeli); // määritellään sille haluttu koko Dimension vastauskoko = new Dimension(100, 600); this.vastauspaneeli.setPreferredSize(vastauskoko); // piirretään vastauspaneeli this.vastauspaneeli.piirra(); // 3. käsitellään otokkapaneeli // jos otokkapaneeli on olemassa if (this.otokkapaneeli != null){ // poistetaan vanha paneeli näkyvistä this.remove(this.otokkapaneeli); } // lisätään uusi otokkapaneeli ikkunaan int otokkaLeveys = 600; int otokkaKorkeus = 600; Dimension otokkaKoko = new Dimension(otokkaLeveys,otokkaKorkeus); if (this.laskupaneeli == null){ otokkaKorkeus = 700; otokkaKoko = new Dimension(otokkaLeveys,otokkaKorkeus); } this.otokkapaneeli = new Otokkapaneeli (this.matikka, this, otokkaLeveys, otokkaKorkeus); this.add(BorderLayout.CENTER, this.otokkapaneeli); // määritellään sille haluttu koko this.otokkapaneeli.setPreferredSize(otokkaKoko); this.otokkapaneeli.piirra(); this.repaint(); // muussa tapauksessa peli on loppu, joten } else { if (this.laskupaneeli != null){ // poistetaan vanha paneeli näkyvistä this.remove(this.laskupaneeli); } if (this.vastauspaneeli != null){ // poistetaan vanha paneeli näkyvistä this.remove(this.vastauspaneeli); } if(this.otokkapaneeli != null){ // poistetaan ötökkäpaneelin ötökät näkyvistä this.otokkapaneeli.tyhjennaOtokkalistat(); this.otokkapaneeli.repaint(); } this.vaihdaAlapaneelinTeksti("Peli loppui!"); Loppudialogi loppudialogi = new Loppudialogi(this, true); loppudialogi.setVisible(true); } } /** * Sisäluokka, joka määrittelee toiminnan menun aloita-vaihtoehdolle. * @author Karoliina Tiuraniemi */ public class AloitaListener implements ActionListener { /** * Metodi, joka aloittaa pelin alusta. * @param event ActionEvent */ public void actionPerformed(ActionEvent event){ Ikkuna.this.peli.nollaaVuorolaskuri(); Ikkuna.this.peli.nollaaTuloslaskuri(); Ikkuna.this.vaihdaAlapaneelinTeksti("Uusi peli!"); Ikkuna.this.uusiLasku(); } } /** * Sisäluokka, joka määrittelee toiminnan menun vaihda taso-vaihtoehdolle. * @author Karoliina Tiuraniemi */ public class VaihdaListener implements ActionListener { /** * Metodi, joka aloittaa pelin alusta toisella tasolla. * @param event ActionEvent */ public void actionPerformed(ActionEvent event){ // nappien otsikot option dialogissa Object[] vaihtoehdot = { "Kyllä", "Ei" }; int n = JOptionPane.showOptionDialog(Ikkuna.this, "Jos vaihdat tasoa kesken pelin, \n" + "asetuksiin mahdolliset tekemäsi muutokset eivät ole enää voimassa. \n" + "Haluatko vaihtaa tasoa?", "Vahvistus", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, //ei omaa ikonia vaihtoehdot, vaihtoehdot[0]); //oletusarvo if (n == 0){ Ikkuna.this.peli.lopetaPeli(); Ikkuna.this.setVisible(false); new Ikkuna(); } } } /** * Sisäluokka, joka määrittelee toiminnan menun Asetukset-vaihtoehdolle. * @author Karoliina Tiuraniemi */ public class AsetusListener implements ActionListener { /** * Metodi, joka aloittaa pelin alusta. * @param event ActionEvent */ public void actionPerformed(ActionEvent event){ Ikkuna.this.label.setText("Asetukset"); Asetusdialogi asetusdialogi = new Asetusdialogi(Ikkuna.this, true); asetusdialogi.setVisible(true); } } /** * Sisäluokka, joka määrittelee toiminnan menun lopeta-vaihtoehdolle. * @author Karoliina Tiuraniemi */ public class LopetaListener implements ActionListener { /** * Metodi, joka sulkee ohjelman. * @param event ActionEvent */ public void actionPerformed(ActionEvent event){ Ikkuna.this.peli.lopetaPeli(); Ikkuna.this.vaihdaAlapaneelinTeksti("Peli loppui!"); System.exit(0); } } /** * @param args */ public static void main(String[] args) { new Ikkuna(); } }