2 Replies Latest reply: May 26, 2011 12:54 PM by 863676 RSS

    Design logic problem - Poker App

    863676
      Hello there,
      I've been coding a Texas Hold'em Odds Calculator for 2-3 weeks now. I've completed the functionality classes which run ok in cmd (tested most of the code maybe needs some more work but you get the idea).

      I've made a class named Table which is basically an API for controlling the other classes. Direct access is not needed to other classes (except some enums and the Card class).

      Now I'm trying to build a GUI that handles this table class graphically. There is the JFrame which just has a reference to the table object.
      I've also made a class named CardPanel which is basically a placeholder for painting cards on the table. It extends JPanel, has a custom paint method and some other methods and has a mouseClickListener that opens a dialog so you can change/clear the card represented from that CardPanel.
      The dialog that appears is a custom JDialog extension. It has a static method getCardDialog(Point) which is called when you want the dialog to be created (did that because I need the return value). Here is the code (removed unnecessary creating components code).
      package TexasHoldemOddsInterface;
      
      import TexasHolemOdds.Card;
      import TexasHolemOdds.CardValue;
      import TexasHolemOdds.Suite;
      import java.awt.Dimension;
      import java.awt.Point;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.util.Arrays;
      import javax.swing.*;
      
      /**
       *
       * @author Dimitris Klimis <dnklimis at gmail.com>
       */
      public class TempCardChooser extends JDialog implements ActionListener {
      
          int x, y;
          Point point;
          Suite suite;
          CardValue cardValue;
          CardAction cardAction = CardAction.CARD_CANCELED;
          JComboBox cbxSuites;
          JComboBox cbxValues;
      
          public enum CardAction {
      
              CARD_SAVED, CARD_CANCELED, CARD_CLEARED
          }
      
          public TempCardChooser(Point point) {
              x = point.x;
              y = point.y;
              this.point = point;
              this.initComponents();
              this.setModal(true);
              this.pack();
              this.setLocation((int) (x - (this.getWidth() / 2.0)), (int) (y - (this.getHeight() / 2.0)));
              this.setResizable(false);
              this.setVisible(true);
          }
      
          private void initComponents() {
              //creating the components
      
              btnCancel.addActionListener(new ActionListener() {
      
                  public void actionPerformed(ActionEvent e) {
                      cardAction = CardAction.CARD_CANCELED;
                      dispose();
                  }
              });
      
              JButton btnSave = new JButton("Save");
      
              btnSave.addActionListener(new ActionListener() {
      
                  public void actionPerformed(ActionEvent e) {
                      cardAction = CardAction.CARD_SAVED;
                      dispose();
                  }
              });
      
              JButton btnClear = new JButton("Clear");
      
              btnClear.addActionListener(new ActionListener() {
      
                  public void actionPerformed(ActionEvent e) {
                      cardAction = CardAction.CARD_CLEARED;
                      dispose();
                  }
              });
      
              //creating and placing components
          }
      
          private CardAction getCardAction() {
              return cardAction;
          }
      
          private Card getCard() {
              return new Card(suite, cardValue);
          }
      
          public static Card getCardDialog(Point point) {
              TempCardChooser chooser = new TempCardChooser(point);
              if (chooser.getCardAction() == CardAction.CARD_SAVED) {
                  return chooser.getCard();
              } else if (chooser.getCardAction() == CardAction.CARD_CLEARED) {
                  return new Card(null, null);
              } else {
                  return null;
              }
          }
      
          public void actionPerformed(ActionEvent e) {
              suite = Suite.values()[cbxSuites.getSelectedIndex()];
              cardValue = CardValue.values()[cbxValues.getSelectedIndex()];
          }
      }
      So this dialog returns a Card object to the CardPanel so it updates it's value and repaint itself.

      Now my problem. The way I do it, each CardPanel holds it's own card information and has no knowledge of other CardPanels' info. So it's possible to select the same card two times in two different CardPanels. Where should I put a list to know which cards are already played? Should I put a static ArrayList in CardPanel? I want to make something that makes sense and I'm not sure if that's the way to go. The JFrame surely shouldn't have a list like that. The Table object has a list like that but I don't want a CardPanel in GUI have a reference to the Table object.

      I don't know if I made my program's structure or logic clear. Please ask any clarification that you may need. Thx in advance... :)

      -Dimitris

      PS. I posted this question to Java forums first but didn't get any answers.

      Edited by: 860673 on May 24, 2011 3:13 PM
        • 1. Re: Design logic problem - Poker App
          jduprez
          Now my problem. The way I do it, each CardPanel holds it's own card information and has no knowledge of other CardPanels' info.
          Why? Why doesn't it pass this information to a model-level class, such as I understand Table is?
          So it's possible to select the same card two times in two different CardPanels. Where should I put a list to know which cards are already played?
          In a model-level class.
          Should I put a static ArrayList in CardPanel?
          <barfing> No.
          I want to make something that makes sense and I'm not sure if that's the way to go. The JFrame surely shouldn't have a list like that.
          The Table object has a list like that but I don't want a CardPanel in GUI have a reference to the Table object
          Why?
          Isn't this class holding all your model data? It's a good design to have the GUI only represent the model (and allow to trigger operations on it).
          If Table encompasses too much data which you want to hide to CardPanel , you can also:
          - design a Hand or Hands or ListOfCards (or whatever makes sense in Poker wording) that contains or exposes only the data needed for CardPanel alone, and Table could contain an array one or more instances of this smaller class.
          - or have Table implement an interface that only exposes what you think is relevant for CardPanel , and have this one have a reference to the Table instance, but typed with the interface (the CardPanel is therefore unaware of whether the object is indeed an instance of Table

          Regards,

          J.
          • 2. Re: Design logic problem - Poker App
            863676
            Hey jduprez, just saw your answer.

            Yes the Table object is a model-level class that connects the GUI with the functional parts of the program. The object has an ArrayList<Card> playedCards. I could pass that reference to the CardPanel via constructor but it didn't felt right writing "new CardPanel(table.getPlayerCards)" for every panel that I make.

            -I could write a small "connecting" class so I won't have to expose the whole table object to the cardPanel but still I have to reference to that through the constructor I guess.

            -I'm not sure how to work with the interface. Write an interface class that both table and cardpanel implement and add to that interface only a method like getPlayedCards?

            I'm a "wannabe" programmer so still I'm trying to get my head straight on some things so thanks for any help... :)