El siguiente código de ejemplo muestra cómo arrastrar una pieza de ajedrez alrededor de un tablero de ajedrez. Utiliza JLayeredPane en lugar de un panel de vidrio, pero estoy seguro de que los conceptos serían los mismos. Es decir:
a) añadir el panel de vidrio para el panel raíz
b) hacer que el panel de vidrio visibles
c) añadir el componente a la placa de vidrio asegurándose de que los límites son válidos
d) utilizar setLocation () para animar el arrastre del componente
Editar: se ha añadido código para fijar 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);
al utilizar controladores de distribución que nunca usa la setSize() o() setBounds métodos. En su caso, simplemente establece el tamaño preferido en (0, 0) ya que este es el tamaño predeterminado de todos los componentes.
Funciona cuando agrega la etiqueta al marco porque el administrador de diseño predeterminado para el panel de contenido del marco es un diseño de borde, por lo tanto, se ignora el tamaño preferido de la etiqueta y el tamaño del marco .
Sin embargo, de forma predeterminada, un JPanel usa un FlowLayout que respeta el tamaño preferido del componente. Como el tamaño preferido es 0, no hay nada que pintar.
Además, el panel de vidrio debe hacerse visible para poder pintarlo.
Le sugiero que lea el Swing tutorial. Hay una sección sobre cómo funcionan los administradores del diseño y sobre cómo funcionan los paneles de vidrio y cada sección tiene ejemplos de trabajo.
Editar: Ejemplo de código añade a continuación:
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);
}
}
Ha intentado establecer el componente como el GlassPane en lugar de añadirlo a la GlassPane? – willcodejavaforfood
Este componente representa un mosaico en un juego de palabras, por lo que solo tiene 37 * 37 y usa bordes para el efecto. No veo cómo podría transformar esto en un panel de vidrio, ya que interferiría con las dimensiones del mosaico. –
¿Podemos ver algún código? Específicamente, cómo agrega el componente al panel de vidrio y lo establece visible. –