I am creating Uno as my final project in my CompSci class.
The cards in playerHandPanel
are made of JButtons. The buttons should be displayed sequentially in the order they were dealt, but also should be overlapping to fit more than the starting 7 cards in the panel.
My teacher suggested I use JLayeredPane
instead of JPanel
as the container because items can be put on different layers.
It didn't work because I was using BoxLayout
to auto-place them with LINE_AXIS
and that layout completely ignores the layers and spaces them as if it was a normal JPanel.
BoxLayout ignoring the layers:
Rather, they should overlap like this:
This is how playerHandPanel
is set up:
public void setupImgs()
{
//gets the dealt hand and sets up the buttons/imgs
for (int i = 0; i < deck.getPlayerHand().size(); i++)
{
setupHand(new JButton(deck.getHandImgs().get(i)), i);
}
}
public void setupHand(JButton img, int index)
{
//TODO allow more than 7 cards in hand
//TODO jlayeredpane to allow overlap by using layers
//boxlayout puts them in sequential but ignores layers >:(
playerHandPanel = new JLayeredPane();
playerHandPanel.setBounds(250, 350, 1400, 300);
playerHandPanel.setBackground(Color.GRAY);
playerHandPanel.setLayout(new BoxLayout(playerHandPanel, BoxLayout.LINE_AXIS));
//using the
if (index == 0)
{
//playerHand1
ph1 = new JButton("", img.getIcon());
ph1.setSize(150, 240);
ph1.setLocation(0, 0);
ph1.setMargin(new Insets(1,1,1,1));
ph1.addActionListener(this);
ph1.addMouseListener(this);//moves up when card focused
playerHandPanel.add(ph1, JLayeredPane.DEFAULT_LAYER);
//placed on bottom-most layer
}
if (index == 1)
{
ph2 = new JButton("", img.getIcon());
ph2.setSize(150, 240);
ph2.setLocation(20, 0);
ph2.setMargin(new Insets(1,1,1,1));
ph2.addActionListener(this);
ph2.addMouseListener(this);
playerHandPanel.add(ph2, JLayeredPane.PALETTE_LAYER);
//placed on second lowest layer
}
if (index == 2)
{
ph3 = new JButton("", img.getIcon());
ph3.setSize(150, 240);
ph3.setLocation(50, 0);
ph3.setMargin(new Insets(1,1,1,1));
ph3.addActionListener(this);
ph3.addMouseListener(this);
playerHandPanel.add(ph3, JLayeredPane.MODAL_LAYER);
//placed on third lowest layer
}
//continued to 7...
window.add(playerHandPanel);
playerHandPanel.setVisible(true);
}
I tried using one or two other layouts, like but couldn't really figure out how they worked.
In the end I just went back to BoxLayout
. I tried GroupLayout
because I thought I could group cards a certain way across layers. I don't really know how to explain it, but it doesn't really matter because it didn't work.
This is what I needed, thanks to @camickr for the comment.
This is very simple and as I said, I don't have much time to try something completely new.
"Check out the Overlap Layout. Think you can also use the FlowLayout with a negative horizontal gap. You will also need to override the isOptimizedDrawingEnabled() to return false on the panel." -@camickr
I will also be adding a rule where the Hgap changes when cards are added to the hand.