Diskuze: OOP problem
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.
Čus,
tak si to zkouším u sebe, nějak mě to sice nejde, nicméně chyba je
jednoznačná (dík za výpis)
Píše to, že ve třídě Gulicka na 47 řádku našel objekt null pointer. To
je jasné - ve třídě Gulicka odkazuješ na atribut hraciePole, ale nikde jej
nenaplňuješ a třída Gulicka jej jednoduše nezná - proto ta exceptiona
Atrament:4.9.2017 21:05
Nemáš ve třídě Gulicka nijak inicializovanou proměnnou hraciePole, takže když na řádku 47 provádíš
hraciePole.nastavPolohu(0,3);
tak to spadne s NullPointerException, protože hraciePole je v ten okamžik null. Což je to co ti říkají první dva řádky chybového výstupu co jsi postnul:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at pacman.Gulicka.keyPressed(Gulicka.java:47)
Musíš někde napřed vytvořit novou instanci třídy HraciePole a s tou pak pracovat - jednu takovou vytváříš ve třídě Okno - to pole1, stačilo by zřejmě pak provést tohle:
...třída Okno...
Gulicka gulicka1=new Gulicka(0,0, this);
this.add(gulicka1);
HraciePole pole1=new HraciePole(6,6);
gulicka1.hraciePole = pole1; //jelikož máš hraciePole v Gulicka definované jako public tak můžeš udělat takto
nicméně z hlediska OOP návrhu to celé nemáš zrovna dobře navržené, bohužel bych musel napsat docela obsáhlý elaborát co všechno je špatně a jak to udělat správně, a na to teď nemám bohužel čas mám na krku dost šibeniční deadline Ale on se určitě najde někdo kdo ti to vysvětli za mně (Lubor Pešek;)
+20 Zkušeností
+2,50 Kč
Ale je tu spousta dalších věcí....
předně supr, že se snažíš o OOP, používáš balíky, dědičnost,
rozhraní... všechno bezva
Ale mám minimálně 3 výhrady (projíždím to jen zběžně)
- nenech si generovat kód od netbeansů, je to blbost a pak ti to udělá neplechu. Je lepší si vše napsat a nastavit, jak potřebuješ
- nepoužívej posluchače, ale radši adapter
Adapter je návrhový vzor, který právě zpřehledňuje posluchače. Abys
implementoval posluchače, musíš (protože je to rozhraní) implementovat
všechny jeho metody. Ale jelikož je málo kdy využiješ úplně všechny, tak
existuje tzv. Adaptér. Je to speciální případ abstraktní třídy, který
je přímo v knihovně java.awt.event.
Jde o to, že adapter implementuje naprázdno všechny třídy, které rozhraní
listenera vyžaduje. Ty si jen zavoláš tu metodu, kterou chceš už
překrýt.
Navíc není třeba tuto abstraktní třídu na tvrdo dědit, stačí ji dobře definovat v kódu. Pochopitelně ti postnu i ukázku:
MOUSE ADAPTER
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JComponent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.Color;
import java.awt.Graphics;
public class MouseAdapterExample extends JFrame {
private JPanel panel;
public MouseAdapterExample() {
init();
addMouseAdapter();
}
private void init() {
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 500);
setLocationRelativeTo(null);
panel = new JPanel();
panel.setSize(500, 500);
add(panel);
panel.setLayout(null);
panel.setBackground(Color.WHITE);
}
private void addMouseAdapter() {
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent evt) {
Circle circle = new Circle();
circle.setSize(10, 10);
circle.setLocation(evt.getX() - circle.getWidth() / 2, evt.getY() - circle.getHeight() / 2);
panel.add(circle);
panel.repaint();
}
});
}
public static void main(String[] args) {
new MouseAdapterExample();
}
private class Circle extends JComponent {
@Override
public void paint(Graphics g) {
g.setColor(Color.GREEN);
g.fillOval(0, 0, getWidth(), getHeight());
}
}
}
KEY ADAPTER
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JComponent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.Color;
import java.awt.Graphics;
public class KeyAdapterExample extends JFrame {
private JPanel panel;
private Circle circle;
public KeyAdapterExample() {
init();
addKeyAdapter();
circle = new Circle();
circle.setSize(10, 10);
circle.setLocation(250, 250);
panel.add(circle);
}
private void init() {
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 500);
setLocationRelativeTo(null);
panel = new JPanel();
panel.setSize(500, 500);
add(panel);
panel.setLayout(null);
panel.setBackground(Color.WHITE);
}
private void addKeyAdapter() {
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent evt) {
switch (evt.getKeyCode()) {
case 37:
circle.moveLeft();
break;
case 38:
circle.moveUp();
break;
case 39:
circle.moveRight();
break;
case 40:
circle.moveDown();
break;
default:
System.err.println("Tož sorry, tento pohyb neznám:(");
}
}
});
}
public static void main(String[] args) {
new KeyAdapterExample();
}
private class Circle extends JComponent {
private int pohyb = 50;
@Override
public void paint(Graphics g) {
g.setColor(Color.GREEN);
g.fillOval(0, 0, getWidth(), getHeight());
}
private void moveLeft() {
setLocation(getX() - pohyb, getY());
}
private void moveUp() {
setLocation(getX(), getY() - pohyb);
}
private void moveRight() {
setLocation(getX() + pohyb, getY());
}
private void moveDown() {
setLocation(getX(), getY() + pohyb);
}
}
}
Ďakujem za vaše rady. Budem sa snažiť použiť ich pri ďalších príkladoch. Ano snažím sa programovať objektovo ale zatiaľ mi to ešte nejak nejde. Prešiel som si lekcie aj príklady tu z ITNETWORK fora a teraz skušam pratkticky to dostať do hlavy. No začiatky sú ťažké.
Skúšal som spraviť zmeny ktoré poradil Atrament a fungujú, takže idem ďaľej zveľaďovať môjho Pacmana - nech už je objektovo aký je Budem múdrejší dobudúcna
Zobrazeno 5 zpráv z 5.