Wednesday, August 21, 2024

Java swing UI for Bridge playing card

BidImage.java

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;

public class BidImage extends JComponent {

    private static final long serialVersionUID = 5119262068248858764L;
    
    public String bidName=null;
    public Dimension dimBidBox=new Dimension(40,20); // width 40 height 20
                                                     // PASS width 60 height 20
    public int mPadding = 3;
    int xP=0,yP=0; // position of screen
    public int fontSize=18;
    boolean isEnable = true;
    
    String club = String.valueOf('\u2663'); // black 2663 white 2667
    String diamond = String.valueOf('\u2666'); // black 2666 white 2662
    String hearth = String.valueOf('\u2665'); // black 2665 white 2661
    String spade = String.valueOf('\u2660'); // black 2660 white 2664
    /*
     * bidName
     * dimBidBox dimension contains width and height
     */
    public BidImage(String bidName) {
        this.bidName = bidName;
        if (bidName.equals("PASS") || bidName.equals("X") || bidName.equals("XX")  ) {
            dimBidBox = new Dimension(60,20);
        }
    }

    public void setEnable(boolean isEnable) {
        this.isEnable = isEnable;
    }
    
    public void setPosition(int x, int y) {
        xP=x;
        yP=y;
    }
    
    public boolean isSelected(int x, int y) {
        return (x>=xP && x<=xP+dimBidBox.width 
                && y>=yP && y<=yP+dimBidBox.height
                && isEnable);
    }
    
    public void drawMe(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        // draw rectangle first
        if (isEnable) {
            // fill color red
            g2d.setColor(Color.GREEN);
            g2d.fillRect(xP, yP, dimBidBox.width, dimBidBox.height);
            g2d.setColor(Color.BLACK);
            g2d.drawRect(xP, yP, dimBidBox.width, dimBidBox.height);
        } else {
            // fill color gray
            g2d.setColor(Color.GRAY);
            g2d.fillRect(xP, yP, dimBidBox.width, dimBidBox.height);
            g2d.setColor(Color.BLACK);
            g2d.drawRect(xP, yP, dimBidBox.width, dimBidBox.height);
        }
        // draw string
        Font font = new Font("Courier", Font.PLAIN, fontSize);
        g2d.setFont(font);
        g2d.setColor(Color.BLACK);
        if (!bidName.endsWith("T")
                && !bidName.equals("PASS")
                && !bidName.equals("X")
                && !bidName.equals("XX") ) {
            char lastChar = bidName.charAt(1);
            char firstChar = bidName.charAt(0);
            String s2Show="";
            switch (lastChar) {
            case 'C':
                s2Show = firstChar+club;
                break;
            case 'D':
                s2Show = firstChar+diamond;
                break;
            case 'H':
                s2Show = firstChar+hearth;
                break;
            case 'S':
                s2Show = firstChar+spade;
                break;
            }
            g2d.drawString(s2Show, xP+mPadding, yP+dimBidBox.height-mPadding);
        } else {
            g2d.drawString(bidName, xP+mPadding, yP+dimBidBox.height-mPadding);           
        }

    }
}

CardImage.java

import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;

public class CardImage extends JComponent {

    private static final long serialVersionUID = -8665119518202165791L;
    
    BufferedImage bImg;
    String cardName;
    int strokeImg=1; // card separator
    int widthImg=100, heightImg=150; // card dimension

    public CardImage(String cardName) {

        this.cardName = cardName;
        // Load image and add stroke as separator
        bImg = new BufferedImage(widthImg,
                heightImg, BufferedImage.TYPE_INT_BGR);
       
        Graphics2D g2d = bImg.createGraphics();
        g2d.setStroke(new BasicStroke(1)); // 1 pixel
       
        // https://stackoverflow.com/questions/31152233/opening-image-asset-java-jdk-8
        String sFName = "/images/"+cardName+".png";
        //System.out.println(sFName); // debug
        BufferedImage img;
        try {
            img = ImageIO.read(getClass().getResource(sFName));

            g2d.drawImage(img, strokeImg, strokeImg, widthImg-(2*strokeImg),
                    heightImg-(2*strokeImg), null);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    int x0=0, x1=0, y0=0, y1=0;
    
    private void setClickArea(int x, int y) {
        x0=x;
        y0=y;
        x1=x0+widthImg;
        y1=y0+heightImg;
        //System.out.println(x0+","+y0+" "+x1+","+y1); // debug
    }
    
    public boolean isSelected(int x, int y) {
        return x>=x0 && x<=x1 && y>=y0 && y<=y1;
    }
    
    /*
     * x position horizontal relatif to panel
     * y position vertical to panel
     */
    public void drawMe(Graphics g, int x, int y, ImageObserver o) {
        setClickArea(x,y);       
        //System.out.println(x0+","+y0+","+x1+","+y1);
        g.drawImage(bImg, x, y, o);
    }
    
    /*
     * 90 degree only, keep on position top left
     */
    public void drawMe90(Graphics g, int x, int y, ImageObserver o) {
        double rotationAngle=90*Math.PI/180;
        AffineTransform transform = new AffineTransform();
        transform.rotate(rotationAngle, x, y);

        // yCenter-heightImg = horizontal position
        // xCenter: vertical position
        transform.translate(x, y-heightImg);
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(bImg, transform, o);       

    }
}

JPanelCenter.java

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class JPanelCenter extends JPanel {

    private static final long serialVersionUID = 1L;
    BidImage bI;
    
    public final static String[] S_BIDS = {
            "1C", // 0
            "1D", // 1
            "1H", // 2
            "1S", // 3
            "1NT", // 4
            "2C", // 5
            "2D", // 6
            "2H", // 7
            "2S", // 8
            "2NT", // 9
            "3C", // 10
            "3D", // 11
            "3H", // 12
            "3S", // 13
            "3NT", // 14
            "4C", // 15
            "4D", // 16
            "4H", // 17
            "4S", // 18
            "4NT", // 19
            "5C", // 20
            "5D", // 21
            "5H", // 22
            "5S", // 23
            "5NT", // 24
            "6C", // 25
            "6D", // 26
            "6H", // 27
            "6S", // 28
            "6NT", // 29
            "7C", // 30
            "7D", // 31
            "7H", // 32
            "7S", // 33
            "7NT" // 34
        };
    ArrayList<BidImage> bids = new ArrayList<>();
    /**
     * Create the panel.
     */
    public JPanelCenter() {
        setPreferredSize(new Dimension(350,290));
        JLabel lblNewLabel = new JLabel("Center");
        add(lblNewLabel);
        bI = new BidImage("7NT");
        //bI = new BidImage("1S");
        int x=30;
        int y=30;
        for (int i=0;i<7;i++) {
            for (int j=0;j<5;j++) {
                int pos=i*5+j;
                BidImage tmp = new BidImage(S_BIDS[pos]);
                tmp.setPosition(x+(i*tmp.dimBidBox.width), y+(j*tmp.dimBidBox.height));
                //tmp.setEnable(false);
                bids.add(tmp);
            }
        }
        BidImage pass = new BidImage("PASS");
        pass.setPosition(100, 140);
        bids.add(pass);
        pass = new BidImage("X");
        pass.setPosition(100+pass.dimBidBox.width, 140);
        bids.add(pass);
        pass = new BidImage("XX");
        pass.setPosition(100+(2*pass.dimBidBox.width), 140);
        bids.add(pass);
        addMouseListener(mListener);
        
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        //bI.setPosition(30, 30);
        //bI.drawMe(g);
        for (int i=0;i<bids.size();i++) {
            BidImage tmp = bids.get(i);
            tmp.drawMe(g);
        }
    }

    /*
     * position x,y relatif to JPanel
     */
    MouseAdapter mListener = new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
               System.out.println(e.getX()+" "+e.getY());
               for (int i=0;i<bids.size();i++) {
                   BidImage cI = bids.get(i);
                   if (cI.isSelected(e.getX(), e.getY())) {
                       System.out.println(cI.bidName);
                       break;
                   }
               }
            }
    };
}

JPanelEast.java

import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JLabel;

public class JPanelEast extends JPanel {

    private static final long serialVersionUID = 1L;
    int panelWidth=85, panelHeight=290;
    ArrayList<CardImage> cards = new ArrayList<>();
    
    /**
     * Create the panel.
     */
    public JPanelEast() {
        setPreferredSize(new Dimension(panelWidth,panelHeight));
        JLabel lblNewLabel = new JLabel("East");
        add(lblNewLabel);
        initCards();

    }
    
    private void initCards() {
        for (int i=0;i<13;i++) {
            CardImage cI = new CardImage("RED");
            cards.add(cI);
        }
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        int x = 0;
        int y = 0;
        for (int i=0;i<13;i++) {
            CardImage cI=cards.get(i);
            cI.drawMe90(g, x, y+(i*10), this);
        }
    }

}

JPanelNorth.java

import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JLabel;

public class JPanelNorth extends JPanel {

    private static final long serialVersionUID = 1L;
    
    int panelWidth=520, panelHeight=85;
    ArrayList<CardImage> cards;
    
    /**
     * Create the panel.
     */
    public JPanelNorth() {
        setPreferredSize(new Dimension(panelWidth,panelHeight));
        JLabel lblNewLabel = new JLabel("North");
        add(lblNewLabel);
       
        addMouseListener(mListener);
       
        initCards();
    }
    
    private void initCards() {
        String[] S_CLUB = {
                "2C",
                "3C",
                "4C",
                "5C",
                "6C",
                "7C",
                "8C",
                "9C",
                "10C",
                "JC",
                "QC",
                "KC",
                "AC"
            };
        cards= new ArrayList<>();
        for (int i=0;i<S_CLUB.length;i++) {
            CardImage cI = new CardImage(S_CLUB[i]);
            cards.add(cI);
        }
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        /*
        int x=0,y=-70;
        for (int i=0;i<cards.size();i++) {
            CardImage cI=cards.get(i);
            cI.drawMe(g, x+((i-1)*15), y, this);
        }
        */
        int x=300,y=-70;
        for (int i=0;i<cards.size();i++) {
            CardImage cI=cards.get(i);
            cI.drawMe(g, x-((i-1)*15), y, this); // 15 gap between cards
        }
       
    }
    
    
    /*
     * position x,y relatif to JPanel
     */
    MouseAdapter mListener = new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
               System.out.println(e.getX()+" "+e.getY());
               // reverse from last draw
               for (int i=cards.size()-1;i>=0;i--) {
                   CardImage cI = cards.get(i);
                   if (cI.isSelected(e.getX(), e.getY())) {
                       System.out.println(cI.cardName);
                       break;
                   }
               }
            }

    };
    
    
}

JPanelSouth.java

import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JLabel;

public class JPanelSouth extends JPanel {

    private static final long serialVersionUID = 1L;

    int panelWidth=520, panelHeight=85;
    ArrayList<CardImage> cards;
    
    /**
     * Create the panel.
     */
    public JPanelSouth() {
        setPreferredSize(new Dimension(panelWidth,panelHeight));
        JLabel lblNewLabel = new JLabel("South");
        add(lblNewLabel);

       
        addMouseListener(mListener);
       
        initCards();
    }
    
    private void initCards() {
        String[] S_DIAMOND = {
                "2D",
                "3D",
                "4D",
                "5D",
                "6D",
                "7D",
                "8D",
                "9D",
                "10D",
                "JD",
                "QD",
                "KD",
                "AD"
            };
        cards= new ArrayList<>();
        for (int i=0;i<S_DIAMOND.length;i++) {
            CardImage cI = new CardImage(S_DIAMOND[i]);
            cards.add(cI);
        }
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        /*
        int x=0,y=-70;
        for (int i=0;i<cards.size();i++) {
            CardImage cI=cards.get(i);
            cI.drawMe(g, x+((i-1)*15), y, this);
        }
        */
        int x=100,y=5;
        for (int i=0;i<cards.size();i++) {
            CardImage cI=cards.get(i);
            cI.drawMe(g, x+((i-1)*15), y, this);
        }
       
        /*
         * test ok
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.BLACK);
        g2d.drawRect(100, 50, 30, 30);
        g2d.drawString("TEST", 100, 50);
        */
    }
    
    /*
     * position x,y relatif to JPanel
     */
    MouseAdapter mListener = new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
               System.out.println(e.getX()+" "+e.getY());
               // reverse from last draw
               for (int i=cards.size()-1;i>=0;i--) {
                   CardImage cI = cards.get(i);
                   if (cI.isSelected(e.getX(), e.getY())) {
                       System.out.println(cI.cardName);
                       break;
                   }
               }
            }
    };

}

JPanelWest.java

import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JLabel;

public class JPanelWest extends JPanel {

    private static final long serialVersionUID = 1L;

    int panelWidth=85, panelHeight=290;
    ArrayList<CardImage> cards = new ArrayList<>();
    
    /**
     * Create the panel.
     */
    public JPanelWest() {
        setPreferredSize(new Dimension(panelWidth,panelHeight));
        JLabel lblNewLabel = new JLabel("West");
        add(lblNewLabel);
        initCards();
    }
    
    private void initCards() {
        for (int i=0;i<13;i++) {
            CardImage cI = new CardImage("BLUE");
            cards.add(cI);
        }
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        int x = -70;
        int y = 0;
        for (int i=0;i<13;i++) {
            CardImage cI=cards.get(i);
            cI.drawMe90(g, x, y+(i*10), this);
        }
    }

}

BridgeUI.java

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;

public class BridgeUI extends JFrame {

    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
    private int width = 520 ;  // 85+350+85
    private int height = 460 ; // 85+290+85
    
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    BridgeUI frame = new BridgeUI();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    
    /**
     * Create the frame.
     */
    public BridgeUI() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(width, height);
        setResizable(false);
        contentPane = new JPanel();
        contentPane.setLayout(new BorderLayout());

        JPanelWest pWest = new JPanelWest();
        contentPane.add(pWest,BorderLayout.WEST);
        JPanelNorth pNorth = new JPanelNorth();
        contentPane.add(pNorth,BorderLayout.NORTH);
        JPanelEast pEast = new JPanelEast();
        contentPane.add(pEast,BorderLayout.EAST);
        JPanelCenter pCenter = new JPanelCenter();
        contentPane.add(pCenter,BorderLayout.CENTER);
        JPanelSouth pSouth = new JPanelSouth();
        contentPane.add(pSouth,BorderLayout.SOUTH);
        
        
        setContentPane(contentPane);
    }

}

Note: 

  1. to place images, follow link
  2. image name's in this code use upper case with extension .png, e.q 2C.png, RED.png


No comments:

Post a Comment