Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Highlighted
New Contributor
Posts: 7
Registered: ‎10-20-2011
My Device: Curve 8530
My Carrier: Koodo

Custom BitmapButtonField not quite working out

[ Edited ]

So I'm a new Java/BB developer, more familiar with PHP than anything. I haven't used Java in a while and made the decidedly ill-advised decision of relearning Java through the Blackberry JDE. I decided to start off with a 'simple' Italian card game. It's pretty messy as I just sort of threw it together as I ran into problems and solved them.

 

My plan was to show the 3 cards in your hand at the bottom, and have them focusable, and selectable. Once selected I want to take the card out of your hand, put it on the table, and change the bitmapField image.

 

I made a custom BitmapButton class that extends BitmapField, making it focusable, and overriding navigtionUnclick(). On nUnclick, it sends a notification to the FieldChangeListener. Problem is, I can't set everything to final, and therefore can't do anything with my buttons now. Is there another method to do what I'm trying to do? I've been searching and rewriting for days.

 

The only way I can refer to any outside objects or variables is to declare them final.

 

while(confusionStatus=="confused"){

    confusionStatus="confused";

}

 

Anyways, here's the code for the BitmapButton:

 

/*
 * BitmapButton.java
 *
 * © <your company here>, <year>
 * Confidential and proprietary.
 */

package Briscola;

import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Graphics;

/**
 * 
 */
public class BitmapButton extends BitmapField {
            
            private Bitmap normal;
            private Bitmap focus;
            
            BitmapButton(Bitmap bitmap, Bitmap focusImg){
                super(bitmap);
                normal = bitmap;
                focus = focusImg;
            }
            
            public boolean isFocusable() {
                return true;
            }
            
            public void onFocus(int direction){
                invalidate();
                setBitmap(focus);
            }
            
            public void onUnfocus(){
                super.onUnfocus();
                invalidate();
                setBitmap(normal);
            }
            
            protected void drawFocus(Graphics _g, boolean _on) {  /* do nothing */ }
        
            protected void paint(Graphics graphics)
            {
                graphics.setColor( 0xF2DE57 );
                super.paint(graphics);
            }
        
            protected boolean navigationUnclick(int status, int time) {
                fieldChangeNotify(0);
                return true;
            }
            
            
    }

 And, here's the area in question:

/*-- Setup Playing Field --*/
                HorizontalFieldManager inPlay = new HorizontalFieldManager();
                BitmapField play1 = new BitmapField(Bitmap.getBitmapResource("Holder.png"));
                BitmapField play2 = new BitmapField(Bitmap.getBitmapResource("Holder.png"));
                BitmapField briskImg = new BitmapField(brisk.face);
                briskImg.setMargin(0,0,0,0);
                play1.setMargin(0,5,0,34);
                inPlay.add(briskImg);
                inPlay.add(play1);
                inPlay.add(play2);
                inPlay.setMargin(10,0,0,10);
                Play.add(inPlay);
                
                int Turn = 1; //P1 Turn                
                
                HorizontalFieldManager inHand = new HorizontalFieldManager();
                /**/one = new BitmapButton(P1.hand[0].face,P1.hand[0].focus);
                /**/two = new BitmapButton(P1.hand[1].face,P1.hand[1].focus);
                /**/three = new BitmapButton(P1.hand[2].face,P1.hand[2].focus);
                FieldChangeListener fcm = new FieldChangeListener() {
                      public void fieldChanged(Field field, int context) {
                        if(context==0){
                            if(field==one){
                                Dialog.alert("first card");
                            }
                            if(field==two){
                                Dialog.alert("second card");
                            }
                            if(field==three){
                                Dialog.alert("third card");
                            }
                        }
                      }
                };      
                one.setChangeListener(fcm);
                two.setChangeListener(fcm);
                three.setChangeListener(fcm);

 I want to change the image of the BitmapButton pressed, as the card shouldn't be in your hand once it's been played obviously, as well as that of either play1 or play2, depending on who's turn it is.

 

The card game is Briscola if anyone is interested.

Developer
Posts: 729
Registered: ‎05-04-2011
My Device: 9700

Re: Custom BitmapButtonField not quite working out

Change your class declaration to:

 

public class BitmapButton extends BitmapField implements FieldChangeListener

and then you would add this method to your class:

 

                      public void fieldChanged(Field field, int context) {                      
if(field==one){
Dialog.alert("first card");
}
if(field==two){
Dialog.alert("second card");
}
if(field==three){
Dialog.alert("third card");
}
}

E.

 

New Contributor
Posts: 7
Registered: ‎10-20-2011
My Device: Curve 8530
My Carrier: Koodo

Re: Custom BitmapButtonField not quite working out

I tried that before, it wouldn't let me use "extends FieldChangeListener" for some reason.

This time, it said I couldn't refer to it from a static context, so I made it static, now the focus/unfocus works, but the button doesn't do anything once clicked.
Developer
Posts: 729
Registered: ‎05-04-2011
My Device: 9700

Re: Custom BitmapButtonField not quite working out

I need to apologize. It seems that I got confused and miss lead you.

 

Let's take one step back.

 

What do you want the application to do once you clicked on a card?

New Contributor
Posts: 7
Registered: ‎10-20-2011
My Device: Curve 8530
My Carrier: Koodo

Re: Custom BitmapButtonField not quite working out

This is my app as it looks now:

 

MainScreen

 

The only difference between that older image and the app now are the lack of the horizontal divider, and instead of the default blue focus, I have a secondary image of the card with a nicer blue border.

 

What I want to happen is when you click on one of the cards at the bottom (your hand), it will change that card to the grey outlines placeholder bitmap from the top, changing one of the placeholders at the top to the image of the card. It will also change the turn so the second player can make his move, or if both players have played, evaluate the winner of the round. When a winner is chosen, another card is dealt to your hand (turning the placeholder into a card from the deck) and the two cards at the top will be placeholders again.

 

The problem is that I can't refer to any of these external objects/classes from within fieldChanged (in my original post).

 

With the new version, including fieldChanged in the BitmapButton.java class, I click on the card and nothing happens.

 

Do I still need to create an EventListener as in my original code?

 

Tell me if I'm rambling.

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Custom BitmapButtonField not quite working out

Let us start a little way back.

 

Fields send 'events' to listeners.  it is the listeners that need to do something with the events that they receive.

 

So buttons don't listen for and act on the click, they just send the click to anyone who has registered an interest.

 

And this is the trick here.  The listener in this case will be  bit of logic that is responsible for the 'table', i.e. the screen that you show us.  It will create the table, add the cards to the table, and register an interest in the cards.  When some action is to take place on the cards, the 'table' will take that action.  So it will move the card from one position on the Table to another.

 

So I suspect you were expecting more from the BitmapButton than you should have.  Think of it as a card position.  Something else needs to manage the card image that is displayed and the actions should the user play that card.

 

An alterntive way to think about this is not to start with the java implementation, but instead start with the Objects.  As a start it appears

a) You have a set of Cards, each of which has an image

b) You have Positions that can hold a card, which they will display if they have one, or an empty slot if they don't   The player can interact with this position (if there is a Card in it)

c) You have a Table which displays a number of these Positions

So now you have three objects. 

(a) looks like a standalone Object with no direct Ui Presence - it will have a a Bitmap and presumably something else you can interact with

(b) looks like a BitmapButton, but a special one that accepts a 'Card' Object and will display that Card's image. 

(c) Looks like a Manager, which lays out the (b) Positions.

 

And in this case it is (c) the Manager that shoud listen for actions taken on your (b) Positoin Objects. 

 

Hope this helps.

New Contributor
Posts: 7
Registered: ‎10-20-2011
My Device: Curve 8530
My Carrier: Koodo

Re: Custom BitmapButtonField not quite working out

Hmm, it does help in a way. In another way I'm just more confused though. How do I go about implementing this, should the login be inside the listener? I still can't manage to modify the fields from the listener. Or have I misunderstood?

New Contributor
Posts: 7
Registered: ‎10-20-2011
My Device: Curve 8530
My Carrier: Koodo

Re: Custom BitmapButtonField not quite working out

This is my code as it is now, if it will give you a better idea of my problem.

 

/*
 * Briscola.java
 *
 * Jordan Zanatta, 2011
 * No rights reserved, have a ball.
 */

package Briscola;

import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import java.util.Random;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Graphics;

/**
 * 
 */
class Briscola extends UiApplication {

    static BitmapButton one;
    static BitmapButton two;
    static BitmapButton three;
    
    public static void main(String[] args) {
        Briscola Game = new Briscola();
        // Create a screen to write on and push it
        // to the top of the screen stack.
        BriscolaScreen Play = new BriscolaScreen();
        
        Game.pushScreen(Play);
        // Set the current thread to notify this application
        // of events such as user input.
        
                Deck deck = new Deck(); //init. deck
                deck.BuildDeck(); //put cards in deck, and shuffle
                Player P1 = new Player(); //initialize players
                Player P2 = new Player();
                P1.pickThree(deck.dealHand()); //each player is dealt three cards
                P2.pickThree(deck.dealHand());
                Card brisk = deck.drawCard(); //pick card to be Briscola suit
                Table playArea = new Table(); //stores cards played to table, as well as who played each
                /*-- Setup Playing Field --*/
                HorizontalFieldManager inPlay = new HorizontalFieldManager();
                BitmapField play1 = new BitmapField(Bitmap.getBitmapResource("Holder.png"));
                BitmapField play2 = new BitmapField(Bitmap.getBitmapResource("Holder.png"));
                BitmapField briskImg = new BitmapField(brisk.face);
                briskImg.setMargin(0,0,0,0);
                play1.setMargin(0,5,0,34);
                inPlay.add(briskImg);
                inPlay.add(play1);
                inPlay.add(play2);
                inPlay.setMargin(10,0,0,10);
                Play.add(inPlay);
                
                int Turn = 1; //P1 Turn
                
                HorizontalFieldManager inHand = new HorizontalFieldManager();
                /**/one = new BitmapButton(P1.hand[0].face,P1.hand[0].focus);
                /**/two = new BitmapButton(P1.hand[1].face,P1.hand[1].focus);
                /**/three = new BitmapButton(P1.hand[2].face,P1.hand[2].focus);

                one.setChangeListener(one);
                two.setChangeListener(two);
                three.setChangeListener(three);
                
                VerticalFieldManager scoreBoard = new VerticalFieldManager();
                LabelField scoreLabel = new LabelField("Score:    ", Field.FIELD_RIGHT);
                LabelField score = new LabelField(P1.score+"    ", Field.FIELD_RIGHT);
                scoreBoard.add(scoreLabel);
                scoreBoard.add(score);
                inHand.add(scoreBoard);
                inHand.setMargin(10,0,0,0);
                one.setMargin(0,5,0,0);
                two.setMargin(0,5,0,0);
                inHand.add(one);
                inHand.add(two);
                inHand.add(three);
                
                inHand.setMargin(5,0,0,10);
                Play.add(inHand);
        
        Game.enterEventDispatcher();
        // don't put any code here – it won't be reached because
        // enterEventDispatcher() does not return.
}
       
    
        public static class Table {
            Card[] inPlay;
            int[] players;
            
            public void playCard(Card cardPlayed, int turn){

            }
            
            public void reset(){
                Card[] inPlay;
                int players;
            }
        }
        
        
        public static class Card {
            int value;
            int suit;
            String valName;
            String suitName;
            Bitmap face;
            Bitmap focus;
            
            public Card (int v, int s, String sn){
                value = v;
                suit = s;
                suitName = sn;
                face = Bitmap.getBitmapResource(suitName+"-"+value+".png");
                focus = Bitmap.getBitmapResource(suitName+"-"+value+" copy.png");
            }
        }
    
    
    public static class Deck {
        Card[] cards = new Card[40];
        int cardsLeft = 0;
        
        public void BuildDeck(){
              String valname="";
             String suitname="";
            
            for(int newSuit = 1; newSuit <= 4; newSuit++){
                if(newSuit==1){
                    suitname="Denari";
                }
                if(newSuit==2){
                    suitname="Bastoni";
                }
                if(newSuit==3){
                    suitname="Coppa";
                }
                if(newSuit==4){
                    suitname="Sword";
                }
                for(int newValue = 0; newValue <= 9; newValue++){
                    cards[cardsLeft] = new Card((newValue+1), newSuit, suitname);
                    cardsLeft++;
                }
            }
            
            /*shuffle deck*/
            for(int a=1;a<=7;a++){
                for ( int i = cards.length-1; i > 0; i-- ) {
                    Random n = new Random();
                    int rand = (int)(n.nextDouble()*(i+1));
                    Card temp = cards[i];
                    cards[i] = cards[rand];
                    cards[rand] = temp;
                }
            }
            /*end shuffle*/
        }
        
        public Card drawCard(){
            cardsLeft--;
            return cards[cardsLeft];
        }
        
        public Card[] dealHand(){
                Card[] deal = new Card[3];
                for(int i=0;i<3;i++){
                    deal[i]=this.drawCard();
                }
                return deal;
        }
        
        
    }
    
    
    public static class Player {
        int score = 0;
        Card[] hand = new Card[3];
        int inHand = 0;
        
        public void pickThree(Card[] dealt){
            for(int i=0;i<3;i++){
                hand[i] = dealt[i];
            }
           inHand=3;
        }
        
    }
    
    
    public static class BitmapButton extends BitmapField implements FieldChangeListener {
            
            private Bitmap normal;
            private Bitmap focus;
            
            BitmapButton(Bitmap bitmap, Bitmap focusImg){
                super(bitmap);
                normal = bitmap;
                focus = focusImg;
            }
            
            public boolean isFocusable() {
                return true;
            }
            
            public void onFocus(int direction){
                invalidate();
                setBitmap(focus);
            }
            
            public void onUnfocus(){
                super.onUnfocus();
                invalidate();
                setBitmap(normal);
            }
            
            protected void drawFocus(Graphics _g, boolean _on) {  /* do nothing */ }
        
            protected void paint(Graphics graphics)
            {
                graphics.setColor( 0xF2DE57 );
                super.paint(graphics);
            }
        
            protected boolean navigationUnclick(int status, int time) {
                fieldChangeNotify(0);
                return true;
            }
            
                     public void fieldChanged(Field field, int context) {
                        if(context==0){
                            if(field==one){
                                Dialog.alert("first card");
                            }
                            if(field==two){
                                Dialog.alert("second card");
                            }
                            if(field==three){
                                Dialog.alert("third card");
                            }
                        }
                      }
    }
    
}

 And yes, I know how horrendous it is, I plan to clean it up once I have a more defined idea of the issue (not really following any development model, I got bored and decided it had to be done).

Developer
Posts: 729
Registered: ‎05-04-2011
My Device: 9700

Re: Custom BitmapButtonField not quite working out

[ Edited ]

Not relevant any more...

 

 

New Contributor
Posts: 7
Registered: ‎10-20-2011
My Device: Curve 8530
My Carrier: Koodo

Re: Custom BitmapButtonField not quite working out

[ Edited ]

Well it seems I've gone about it the wrong way from the start.

 

I'm trying to use your model but now I'm not quite sure where to intialize my BriscolaScreen (extends MainScreen). If I do it in main() I can't add my FieldManagers to it.

 

EDIT: Oh it seems you've overwritten your model...