Op deze website gebruiken we cookies om content en advertenties te personaliseren, om functies voor social media te bieden en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor social media, adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services. Meer informatie.

Akkoord

Vraag & Antwoord

Programmeren

[Java] Relaties tussen klassen bij AWT GUI

marientje
11 antwoorden
  • Ik zit met een lastig probleempje. Ik ben nog beginner, dus ik hoop dat ik het een beetje duidelijk uit kan leggen. Als iets onduidelijk is, vraag maar raak.

    [img:a882e45c44]http://mike.wilkoffie.nl/GUI.gif[/img:a882e45c44]

    Het is een GUI waarbij je links gegevens van RPG karakters kunt zien, in het midden een lijstje met karakters en rechts mogelijkheden tot filteren van de lijst.

    Ik heb een class ControllerFrame. In dat ControllerFrame heb het volgende gedaan:

    KarakterPanel karPanel = new KarakterPanel;
    (…)
    LijstPanel lijstPanel = new LijstPanel;
    (…)
    FilterPanel filterPanel = new FilterPanel;

    Ik moet nu een methode setKarakter maken, waarmee karPanel bijgewerkt wordt, wanneer je op een karakter in het lijstje klikt. Ik vraag me af in welke class ik die moet maken en hoe die er ongeveer uit moet zien.
    En alle knopjes moeten werken.

    Blijkbaar begrijp ik dus niet helemaal hoe de relatie tussen klassen werkt en dus hoe je een methode maakt die iets met de 3 panels doet.

    Hier mijn classdiagram, zodat jullie het beter snappen (niet helemaal volledig en correct).
  • Ik neem aan dat je LijstPanel 'luistert' naar wat de gebruker doet (klikken op een van de opties).
    setKarakter() moet natuurlijk in KarakterPanel staan, want die laat t karakter zien. De enige (nette) manier om te zorgen dat LijstPanel daar bij kan, is door KarakterPanel mee te geven aan de constructor van LijstPanel. Dit gebeurt heel vaak

    ControllerFrame.java:
    [code:1:fef91587ce]KarakterPanel karPanel = new KarakterPanel(params);
    LijstPanel lijstPanel = new LijstPanel(KarakterPanel karPanel, params);
    FilterPanel filterPanel = new FilterPanel;[/code:1:fef91587ce]
    LijstPanel.java:
    [code:1:fef91587ce]class LijstPanel {
    KarakterPanel karPanel;

    LijstPanel(KarakterPanel karPanel, params) {
    this.karPanel = karPanel;
    }

    onClick() {
    karPanel.setKarakter();
    }

    } [/code:1:fef91587ce]

    om tekunnen reageren op een button-click moet je ActionListener implementen, addActionListener() aanroepen voor elke button en in ActionPerformed() kan je dan iets doen wanneer op een vd buttons is geklikt (GOOGLE!)
    Wanneer je gebruik maakt van SWING wordt t allemaal iets lastiger
  • Bedankt, ik ga even prutsen.
    ActionListeners heb ik al.

    [code:1:5d2cf859b4]
    public class TestFrame extends Frame {
    public static void main(String[] args){
    (…Frame maken…)
    }

    public TestFrame{
    (3 panels maken en de 5 buttons + lijst actionlisteners geven)
    }

    (…)

    class NieuwButtonListener implements ActionListener{{
    public void actionPerformed(ActionEvent e){
    (…)
    lijstPanel.lijst.add(karPanel.getKarakter().getName().toString());
    karlist1.voegToe(karPanel.getKarakter());
    // Vervelende is dat lijst static gemaakt moet worden, omdat lijst in
    // een andere class wordt aangemaakt.
    (…)
    }
    }

    (…)
    }
    [/code:1:5d2cf859b4]
  • [quote:474de02d98]// Vervelende is dat lijst static gemaakt moet worden, omdat lijst in
    // een andere class wordt aangemaakt. [/quote:474de02d98]
    Dat hoeft niet, en doe dat vooral ook niet als je objecten meegeeft aan de constructors zoals in mn voorbeeld.

    Verder hoor ik t wel
  • Het gaat al een stuk beter (zonder static ja).
    Het werkt helemaal, op 1 ding na.
    Ik zit nog wat te klungelen met de setKarakters methode…

    Het panel links kan een HumanPanel of OrcPanel zijn (subklassen van KarakterPanel).

    Wanneer je de Choice verandert, krijgt hij een Item event binnen en moet hij het panel verversen.
    Hij verwijderd van het frame en opnieuw toegevoegd met een human/orc als parameter.
    Vlak voor het verwijderen leest hij de velden uit en slaat dat op in een Karakter en moet die daarna weer worden neergezet, zodat de velden na de refresh niet gereset zijn.

    Dus
    [code:1:f33d51a399]
    public void updatePanel(String ras) throws Exception{
    // Waarden opslaan
    Karakter tempkarakter = karakterPanel.getKarakter();

    // Kijken of rasChoice Human of Orc is en dat type panel aanmaken
    if(ras.equals("Human")){
    // HumanPanel maken
    remove(karakterPanel);
    karakterPanel = new HumanPanel();
    karakterPanel.setBounds(30,35,200,235);
    add(karakterPanel);
    karakterPanel.rasChoice.select("Human");
    }

    else if(ras.equals("Orc")){
    //OrcPanel maken
    remove(karakterPanel);
    karakterPanel = new OrcPanel();
    karakterPanel.setBounds(30,35,200,235);
    add(karakterPanel);
    karakterPanel.rasChoice.select("Orc");
    }

    // Listeners opnieuw activeren en gegevens erin zetten
    //karakterPanel.setKarakter(tempkarakter);
    karakterPanel.rasChoice.addItemListener(new rasChoiceListener());
    karakterPanel.addNewButton.addActionListener(new AddNewButtonListener());

    }
    [/code:1:f33d51a399]
    Probleem is alleen dat tempkarakter een Karakter is en geen Human of Orc…. Dus karakterPanel = new OrcPanel(tempkarakter) werkt niet
  • volgens mij maak je t jezelf nu wel erg ingewikkeld en kan je gewoon doen
    if(ras.equals("Human")){
    // HumanPanel maken
    karakterPanel = new HumanPanel();
    karakterPanel.rasChoice.select("Human");
    }

    else if(ras.equals("Orc")){
    //OrcPanel maken
    karakterPanel = new OrcPanel();
    karakterPanel.rasChoice.select("Orc");
    }

    overigens kan je karakterPanel.rasChoice.select("Orc");
    denk ik beter in de construcotr zetten, aangezien je dit nu voor beiden doet maar afhakenlijk van t soort.
    Tenzij een andere keer dat een object van dit type wordt gemaakt dat niet moet gebeuren.
    en actionlisteners hoeven ook maar een keer worden toegevoegd. Dus in de construcotr van KarakterPanel
  • klopt, maar ik denk dat je 1 ding over het hoofd ziet. (tjek even de GUI in mijn startpost).

    Het verschil tussen de OrcPanel en HumanPanel (subclassen van KarakterPanel) is dat de onderste 2 Labels en Textfields anders zijn. Human heeft Greed en MaxGreed, Orc heeft Berserk en MaxBerserk.
    Dus als je de choice verandert, zou het panel moeten veranderen, maar de waarden er wel in blijven staan.
  • in dat geval moet je m 'casten' met t risico op een runtime-error

    maar ik zie niet waar je die tempkarakter voor nodig hebt
  • De textfields bevatten waarden. Als updatePanel(String ras) wordt aangeroepen, verandert hij misschien van een humanPanel naar een OrcPanel. Wanneer dan karakterPanel = new HumanPanel() komt, ben je al je waarden kwijt (omdat het een new panel is), dus de velden zijn weer gevuld met de waarden die de contructor bevatten

    Dus als je eerst een tempkarakter aanmaakt, daarna het panel (danwel Orc, danwel Human) opnieuw maakt en tempkarakter meegeeft, blijven je velden gevuld.
    Dus karakterPanel = new HumanPanel((Human)tempkarakter);
  • A, maar dat had je eerst niet staan :wink:
    Volgens mij werkt t zo, of is er nog een vraag?
  • Ik ben bijna klaar met het hele programma (tis namelijk een opdracht voor studie, die vrijdag klaar moet zijn).
    Alles werkt perfect, op die rasChoice na…

    Op het moment dat hij een actionEvent binnen krijgt doet hij dus dit:
    Karakter tempkarakter = karakterPanel.getKarakter();

    Afhankelijk van of je "Orc" of "Human" doet, dan doet hij dus (stel Human):
    [code:1:06d702a275]remove(karakterPanel);
    karakterPanel = new HumanPanel((Human)tempkarakter);[/code:1:06d702a275]

    System.out.println("tempkarakter is
    "+tempkarakter);
    geeft goed weer wat er in tempkarakter zit, met ras en al.

    Het enige is, wanneer ik het programma uitvoer krijg ik inderdaad een exception, namelijk
    [quote:06d702a275]java.lang.ClassCastException: <ras>[/quote:06d702a275] waarbij <ras> Human of Orc is, naar gelang de choice die je geselecteerd heb.
    Dit komt vast omdat als je eerst een Orc hebt, die vervolgens in tempkarakter wordt gezet. Dan kun je die tempkarakter niet weer in een HumanPanel inladen…

    Weten jullie (jij :)) de velden na de 'refresh' ingevuld blijven?

Beantwoord deze vraag

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.