Mã ví dụ bên dưới minh họa cách kéo một quân cờ chung quanh bàn cờ. Nó sử dụng JLayeredPane thay vì một khung kính, nhưng tôi chắc chắn rằng các khái niệm sẽ giống nhau. Đó là:
a) thêm khung kính để cửa sổ gốc
b) làm cho các cửa sổ kính có thể nhìn thấy
c) thêm các thành phần để cửa sổ kính đảm bảo các giới hạn có giá trị
d) sử dụng setLocation () để animate kéo của các thành phần
Edit: thêm mã để sửa chữa SSCCE
JLabel l = new JLabel();
l.setText("Hello");
l.setBorder(new LineBorder(Color.BLACK, 1));
// l.setPreferredSize(l.getSize());
// l.setBounds(10, 10, 50, 20);
((JPanel)mf.getGlassPane()).add(l);
mf.setVisible(true);
mf.getGlassPane().setVisible(true);
Khi sử dụng quản lý bố trí bạn không bao giờ sử dụng setSize() hoặc setBounds() phương pháp. Trong trường hợp của bạn, bạn chỉ cần đặt kích thước ưa thích thành (0, 0) vì đây là kích thước mặc định của tất cả các thành phần.
Nó hoạt động khi bạn thêm nhãn vào khung vì trình quản lý bố cục mặc định cho khung nội dung của khung là bố cục đường viền, do đó kích thước của nhãn được bỏ qua và nhãn được tạo thành kích thước của khung .
Tuy nhiên, theo mặc định, JPanel sử dụng FlowLayout không tôn trọng kích thước ưa thích của thành phần. Vì kích thước ưa thích là 0, nên không có gì để vẽ.
Ngoài ra, ngăn kính phải được hiển thị để nó được sơn.
Tôi khuyên bạn nên đọc Swing tutorial. Có phần về cách các nhà quản lý bố cục hoạt động và cách các ô kính hoạt động và mỗi phần có các ví dụ làm việc.
Chỉnh sửa: Mã Ví dụ thêm dưới đây:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class ChessBoard extends JFrame implements MouseListener, MouseMotionListener
{
JLayeredPane layeredPane;
JPanel chessBoard;
JLabel chessPiece;
int xAdjustment;
int yAdjustment;
public ChessBoard()
{
Dimension boardSize = new Dimension(600, 600);
// Use a Layered Pane for this this application
layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(boardSize);
layeredPane.addMouseListener(this);
layeredPane.addMouseMotionListener(this);
getContentPane().add(layeredPane);
// Add a chess board to the Layered Pane
chessBoard = new JPanel();
chessBoard.setLayout(new GridLayout(8, 8));
chessBoard.setPreferredSize(boardSize);
chessBoard.setBounds(0, 0, boardSize.width, boardSize.height);
layeredPane.add(chessBoard, JLayeredPane.DEFAULT_LAYER);
// Build the Chess Board squares
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 ? Color.red : Color.white);
chessBoard.add(square);
}
}
// Add a few pieces to the board
ImageIcon duke = new ImageIcon("dukewavered.gif"); // add an image here
JLabel piece = new JLabel(duke);
JPanel panel = (JPanel)chessBoard.getComponent(0);
panel.add(piece);
piece = new JLabel(duke);
panel = (JPanel)chessBoard.getComponent(15);
panel.add(piece);
}
/*
** Add the selected chess piece to the dragging layer so it can be moved
*/
public void mousePressed(MouseEvent e)
{
chessPiece = null;
Component c = chessBoard.findComponentAt(e.getX(), e.getY());
if (c instanceof JPanel) return;
Point parentLocation = c.getParent().getLocation();
xAdjustment = parentLocation.x - e.getX();
yAdjustment = parentLocation.y - e.getY();
chessPiece = (JLabel)c;
chessPiece.setLocation(e.getX() + xAdjustment, e.getY() + yAdjustment);
layeredPane.add(chessPiece, JLayeredPane.DRAG_LAYER);
layeredPane.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
}
/*
** Move the chess piece around
*/
public void mouseDragged(MouseEvent me)
{
if (chessPiece == null) return;
// The drag location should be within the bounds of the chess board
int x = me.getX() + xAdjustment;
int xMax = layeredPane.getWidth() - chessPiece.getWidth();
x = Math.min(x, xMax);
x = Math.max(x, 0);
int y = me.getY() + yAdjustment;
int yMax = layeredPane.getHeight() - chessPiece.getHeight();
y = Math.min(y, yMax);
y = Math.max(y, 0);
chessPiece.setLocation(x, y);
}
/*
** Drop the chess piece back onto the chess board
*/
public void mouseReleased(MouseEvent e)
{
layeredPane.setCursor(null);
if (chessPiece == null) return;
// Make sure the chess piece is no longer painted on the layered pane
chessPiece.setVisible(false);
layeredPane.remove(chessPiece);
chessPiece.setVisible(true);
// The drop location should be within the bounds of the chess board
int xMax = layeredPane.getWidth() - chessPiece.getWidth();
int x = Math.min(e.getX(), xMax);
x = Math.max(x, 0);
int yMax = layeredPane.getHeight() - chessPiece.getHeight();
int y = Math.min(e.getY(), yMax);
y = Math.max(y, 0);
Component c = chessBoard.findComponentAt(x, y);
if (c instanceof JLabel)
{
Container parent = c.getParent();
parent.remove(0);
parent.add(chessPiece);
parent.validate();
}
else
{
Container parent = (Container)c;
parent.add(chessPiece);
parent.validate();
}
}
public void mouseClicked(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public static void main(String[] args)
{
JFrame frame = new ChessBoard();
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Các bạn đã cố gắng thiết lập thành phần của bạn AS các glasspane thay vì thêm nó vào glasspane? – willcodejavaforfood
Thành phần này đại diện cho một ô trong trò chơi chữ, vì vậy nó chỉ là 37 * 37 và sử dụng đường viền để có hiệu lực. Tôi không thấy làm thế nào tôi có thể biến đổi điều này thành một ngăn kính vì nó sẽ gây rối với kích thước của gạch. –
Chúng ta có thể thấy một số mã không? Cụ thể là cách bạn thêm thành phần vào ngăn kính và đặt nó hiển thị. –