0

I'm writing a small Java program that randomly deals out playing cards, then displays them on screen in a window.

Since I'm using NetBeans, the GUI was started for me, and I've been writing my methods for randomly choosing cards, setting up an array to store whether or not a card has already been dealt, etc., all in the same class NetBeans set up for me when it built the JFrame.

I'd like to move all my non-GUI code into its own Class, and then just pass data back to the GUI class as needed to display the cards, but I'm not sure of the best way to share data between the two classes.

I know about set/get methods and I know I could make public class-level variables, but everything I've been reading tells me to avoid both as much as possible.

Right now I have a method that generates an int between 1 and 52 for each card dealt. 1 = Ace of spades, 2= 2 of spades, etc. Once the GUI has that number, it can display the appropriate card in the appropriate place on the screen (or at least it will be able to once I've coded the GUI side of things). If I'm looking to pass that integer value to the GUI class, then display a specific card on the screen based on that value, how should I do it?

Seems to me a public variable would make this easy, as would a simple get method...but in the interest of avoiding those options is there another way?

I can provide code snippets if that helps.

Merlin2600
  • 68
  • 7
  • *"but everything I've been reading tells me to avoid both as much as possible"* - Really? Most OO principles suggest avoiding public fields (variables) and prefer access via methods – MadProgrammer Jul 27 '15 at 03:36
  • Why do you want to avoid a get method? – M. Shaw Jul 27 '15 at 03:38
  • 1
    The GUI should task you generator class for the value, the GUI should not care how that value is generated, just that it is generated in a consistent and documented manner. To my find, this calls for a method (as it's a calculated value). Another solution would be to use an observer pattern, where the GUI registers interest in the generation code and when a value gets generated, it is notified via (what Swing calls) a listener, but to my mind, this seems overkill for your purposes – MadProgrammer Jul 27 '15 at 03:39
  • 1
    As a rule of thumb - Public Variables are a no-no, but Public Methods to access private variables, or perform actions are standard. – TomDillinger Jul 27 '15 at 03:39
  • 1
    I suggest that you do whatever's easiest (which is probably public variables), until you know enough about Java (and programming) to understand why other people recommend not using them. (It's good to find out for yourself why things are considered bad) – user253751 Jul 27 '15 at 03:53
  • I agree with Immibis to a point, however I also think that there are valid reasons to not use public variables that are worth reading about rather than running into yourself. Getters and Setters are actually the proper way to do it, so I'd really like to see what you read that says not to use them. – Nash Read Jul 27 '15 at 04:03
  • My answer suggests using a get method (also includes an example of a set method), as the Java standards go...Perhaps see [why global variables are bad](http://c2.com/cgi/wiki?GlobalVariablesAreBad) for information about that. Good luck! – hmc_jake Jul 27 '15 at 04:11
  • To answer Nash Read's question, I came across this question, among others: http://stackoverflow.com/questions/9416245/how-to-avoid-getters-and-setters – Merlin2600 Jul 27 '15 at 23:33
  • @NashRead See his reply if you're interested in seeing what he read. – hmc_jake Jul 28 '15 at 01:16

1 Answers1

1

Here's one way you could start to implement this idea using OO concepts.

Make a Card class to represent a card.

public class Card {
    // FIELDS
    // card name
    private final String name;
    // card value (number)
    private final int value;
    // another arbitrary value to demonstrate setter
    private Object arbitraryValue;


    public Card(String name, String value) {
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return this.name;
    }

    public int getValue() {
        return this.value;
    }

    public Object getArbitraryValue() {
        return this.arbitraryValue;
    }

    public void setArbitraryValue(Object arbitraryValue) {
        this.arbitraryValue = arbitraryValue;
    }
}

Create a CardManager class to hold methods that pertain to handling cards (e.g. utility methods and card data storage)

public class CardManager() {
    private List<Card> cards = new ArrayList<Card>();

    public void addCard(Card card) {
        this.cards.add(card);
    }

    // and so on...your methods here.
}

Finally, create a class for your GUI (CardGUI) management and make use of the other classes to manage it.

You can do so like this:

public class CardGUI() {
    public static void main(String[] args) {
        // create your GUI and put your logic here...
        // also use your other classes, perhaps like so.
        Card card = new Card("One", 1);
        CardManager cardManager = new CardManager();
        cardManager.addCard(card);

        // From there you can manage your cards through other classes.
}

Hope this helps / demonstrates how to share data between classes following standards.

Edit: To answer your question on exactly how you would get the value, then see the above Card class. You would simple create a new card (Card card = new Card("name", intval);), then you would use the method Card#getValue() to get that value and display it in the GUI.

hmc_jake
  • 372
  • 1
  • 17
  • Thanks for the answers and input, it's all very helpful. If I'm understanding the concepts correctly, get/set can be bad because they still limit your ability to modify your objects and classes sometime down the line, and if you have a lot of them they can make code management a nightmare. Public variables are subject to tinkering and tampering by those using your code, which can be its own issue. I'm sure there are more complex and subtle issues at play, but that's how I understand it so far. – Merlin2600 Jul 28 '15 at 00:26
  • 1
    @scudder Indeed. However, for your type of program, including getters/setters is common practice and even recommended. – hmc_jake Jul 28 '15 at 00:28
  • 1
    @scudder If you're worried about how they make your code look, then you can try projectlombok. It's a project that allows you to replace creating getters/setters with annotations on your variable declarations like `[at]Getter`, `[at]Setter`, and `[at]Data`. I use it for my projects, to avoid the constant getX(), setY(), etc, declarations. Anyway, getters/setters are usually the way to go to access out-of-class data and they're the safest. – hmc_jake Jul 28 '15 at 00:43