2012-09-12 45 views
3

我在尝试使用JLayeredPane进行自己的国际象棋游戏时遇到问题。调整JLayeredPane图层

我能走到今天:

No side panels

(希望你可以看到块G6对标签呈现出绿色的边框将其选中块)

但是,当我加我2个SidePanel小号我的ChessBoard面板,然后有另一层顶部与标签应该涵盖每个板块,但它没有:

With sidepanels

正如您所看到的绿色边框周围块G2已关闭。

当我将SidePanel s添加到ChessBoard并将其添加到底层并将其大小设置为600x600时,我已将其缩小到显而易见的范围,然后添加标签的顶层以适合ChessBoard,并且围绕选定的JLabel(以及更低的ChessBoard方块[黑色或白色])绘制绿色边框,由于SidePanel s已将棋盘的实际尺寸减小到600x600,所以它现在将会是600-sp1.getWidth() x 600-sp2.getHeight()。我尝试设置顶层的边界和首选大小来弥补它,但似乎没有用。任何帮助表示赞赏谢谢:

ChessBoardTest.java:

import java.awt.*; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.util.HashMap; 
import javax.swing.*; 
import javax.swing.border.BevelBorder; 

public class ChessBoardTest { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 

       Dimension boardSize = new Dimension(600, 600); 

       JFrame frame = new JFrame("Chess JLayeredPane Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setResizable(false); 

       Container contentPane = frame.getContentPane(); 

       ChessBoard chessBoard = new ChessBoard(); 
       SidePanel sp1 = new SidePanel(new String[]{"8", "7", "6", "5", "4", "3", "2", "1"}, SidePanel.VERTICAL); 
       SidePanel sp2 = new SidePanel(new String[]{"A", "B", "C", "D", "E", "F", "G", "H"}, SidePanel.HORIZONTAL); 

       //adding these 2 side panels messes up the layout 
       chessBoard.add(sp1, BorderLayout.WEST); 
       chessBoard.add(sp2, BorderLayout.SOUTH); 

       chessBoard.setPreferredSize(boardSize); 
       chessBoard.setBounds(0, 0, boardSize.width, boardSize.height); 

       ChessPieceLayer chessPieceLayer = new ChessPieceLayer(); 

      //chessPieceLayer.setPreferredSize(boardSize); 
      //chessPieceLayer.setBounds(0, 0, boardSize.width, boardSize.height); 

      //i've tried resizing to make up for the side panels but no result 
      chessPieceLayer.setPreferredSize(new Dimension(600-sp1.getWidth(),600-sp2.getHeight())); 
      chessPieceLayer.setBounds(0+sp1.getWidth(), 0+sp2.getHeight(), 600-sp1.getWidth(), 600-sp2.getHeight()); 




       JLayeredPane jLayeredPane = new JLayeredPane(); 
       jLayeredPane.setPreferredSize(boardSize); 

       jLayeredPane.add(chessBoard, JLayeredPane.FRAME_CONTENT_LAYER); 
       jLayeredPane.add(chessPieceLayer, JLayeredPane.MODAL_LAYER); 

       contentPane.add(jLayeredPane); 
       frame.pack(); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 

SidePanel.java:

class SidePanel extends JPanel { 

    final static String HORIZONTAL = "horizontal"; 
    final static String VERTICAL = "vertical"; 

    public SidePanel(String[] strings, String direction) { 
     if (direction.equals(VERTICAL)) { 
      setLayout(new GridLayout(8, 0)); 
     } else { 
      setLayout(new GridLayout(0, 8)); 
     } 
     setDoubleBuffered(true); 
     for (String string : strings) { 
      this.add(new JLabel(string, JLabel.CENTER)); 
     } 

    } 
} 

ChessBoard.java:

class ChessBoard extends JPanel { 

    public ChessBoard() { 
     super(new BorderLayout(), true); 

     this.add(populateBoard(Color.white, Color.black), BorderLayout.CENTER); 
    } 

    private JPanel populateBoard(Color c1, Color c2) { 
     JPanel panel = new JPanel(new GridLayout(8, 8)); 
     for (int i = 0; i < 8; i++) { 
      for (int j = 0; j < 8; j++) { 
       JPanel square = new JPanel(new BorderLayout()); 
       square.setBackground((i + j) % 2 == 0 ? c1 : c2); 
       panel.add(square); 
      } 
     } 
     return panel; 
    } 
} 

ChessPieceLayer.java:

class ChessPieceLayer extends JComponent { 

    private HashMap<PiecePanel, String> panelsMap = new HashMap<>(64); 
    final ChessPieceMouseListener listener; 

    ChessPieceLayer() { 
     super(); 
     listener = new ChessPieceMouseListener(); 
     setLayout(new GridLayout(8, 8)); 
     setDoubleBuffered(true); 

     fillPanelsMap(); 
    } 

    private void fillPanelsMap() { 
     String[] cols = new String[]{"A", "B", "C", "D", "E", "F", "G", "H"}; 
     int[] rows = new int[]{1, 2, 3, 4, 5, 6, 7, 8}; 
     String row, col; 
     int rowCount = 7, colCount = 0, trigger = 8; 

     for (int i = 0; i < 64; i++) { 

      if (trigger == 0) { 
       colCount = 0; 
       trigger = 8; 
       rowCount--; 
      } 
      col = cols[colCount++]; 
      row = rows[rowCount] + ""; 
      trigger--; 

      String location = col + row; 

      PiecePanel square = createAndAddPiecesWithMouseListener(location); 

      panelsMap.put(square, location); 

     } 
    } 

    private PiecePanel createAndAddPiecesWithMouseListener(String location) { 
     PiecePanel square = new PiecePanel(location, JLabel.CENTER); 
     square.addMouseListener(listener); 
     square.setText(location); 
     this.add(square); 
     return square; 
    } 
} 

PiecePanel.java:

class PiecePanel extends JLabel { 

    private String location; 

    public PiecePanel(String text, int horizontalAlignment) { 
     super("", horizontalAlignment); 
     this.location = text; 
    } 

    PiecePanel(String location) { 
     this.location = location; 
    } 

    public String getPieceLocation() { 
     return location; 
    } 

    public void setPieceLocation(String location) { 
     this.location = location; 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
    } 
} 

ChessPieceMouseListener.java:

class ChessPieceMouseListener implements MouseListener { 

    int counter = 0; 
    PiecePanel this_pp, prev_pp; 

    @Override 
    public void mouseClicked(MouseEvent e) { 
    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
     PiecePanel pp = (PiecePanel) e.getComponent(); 
     if (counter == 0) { 
      this_pp = pp; 
      this_pp.setBorder(new BevelBorder(0, Color.green, Color.green)); 
      JOptionPane.showMessageDialog(null, "From " + pp.getPieceLocation()); 
      counter = 1; 
     } else { 
      prev_pp = this_pp; 
      this_pp = pp; 
      prev_pp.setBorder(null); 
      JOptionPane.showMessageDialog(null, "To " + pp.getPieceLocation()); 
      counter = 0; 
     } 
    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 
    } 

    @Override 
    public void mouseExited(MouseEvent e) { 
    } 
} 

在第一我使用:

chessPieceLayer.setPreferredSize(boardSize); 
chessPieceLayer.setBounds(0, 0, boardSize.width, boardSize.height); 

然后我尝试:

chessPieceLayer.setPreferredSize(new Dimension(600-sp1.getWidth(),600-sp2.getHeight())); 
chessPieceLayer.setBounds(0+sp1.getWidth(), 0+sp2.getHeight(), 600-sp1.getWidth(), 600-sp2.getHeight()); 

但结果犯规不同

+1

你可以张贴棋盘和ChessPiecePlayer的代码? –

+0

@GuillaumePolet在那里。正在使用内部类,所以它们没有在自己的文件中声明,当然这只是测试。但我现在将其分开以便于查看 –

+0

另请参阅此[示例](http://stackoverflow.com/a/2562685/230513)和[变体](http://stackoverflow.com/a/2563350/230513)。 – trashgod

回答

4

好吧,我发现这个问题并没有一个简单的解决方案。下一次,尝试把你的代码放在一个类中,这样我就不需要做太多的复制/粘贴操作(这种方式阻止人们尝试你的代码);-)。

无论如何,问题来自您的SidePanel,它会占用您ChessBoardPanel上的空间,因此会引入偏移量。解决的办法很简单,所有你需要做的是:

  1. 添加sp1sp2contentPane
  2. chessBoardchessPieceLayer简单地设置大小boardSize。

说明

  1. 我们移动侧面板的内容窗格,使他们不与你的图层干扰。当你使用JLayeredPane时,你使用所谓的绝对布局或空布局。这意味着您必须注意组件的位置和大小。这导致我点2:
  2. 当没有LayoutManager时,设置preferredSize是没有用的,因为没有LayoutManager调用该方法。现在,默认组件位于(0,0)中,因此您只需致电setSize即可。如果你希望他们被抵消-ED,你也需要调用setLocation,或在一个单一的通话串联这两个调用setBounds
+0

+1很棒的东西谢谢你 –