我有一个包含11个JPanel的JLabels,每个JLabels都注册了一个类似于这样的MouseMotionListener (由Netbeans生成):
label1.addMouseMotionListener(new MouseMotionAdapter()
{
public void mouseDragged(MouseMotionEvent evt){
label1MouseDragged(evt);
}独立的labelXMouseDragged方法包含(例如):
label1.setLocation(label1.getParent().getMousePosition());该小组与其他各种控制一起生活在另一个小组内。我发现我可以在面板中很好地拖动我的标签(我让我的方法正确地检查了边界,但是为了简单起见,我已经将它们保留在上面了)。但是,如果在非控件的任何地方单击鼠标,无论是在内部面板中还是在父面板中,标签的位置都会重置。是什么导致了这一切?我没有任何类型的mouseListeners注册任何其他地方,如果我自己做这个面板,我似乎没有问题的点击。
发布于 2014-01-21 02:56:21
您可以通过使用 layout来实现这一点,但是我对null布局有一种病理上的厌恶,太多事情都会出错。
Swing API基于布局管理器在布局组件时的使用。
相反,您可以创建一个布局管理器,其唯一责任是履行它所管理的组件的位置。

这样做的基本好处是,您不需要担心组件的大小大小,它将响应对父容器的更改以及对其周围容器的更改,而无需添加额外的侦听器。
您甚至可以在layoutContainer中设计一个边界检查,以确保组件保持在范围内。
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.LayoutManager2;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class AbsoluteLayoutExample {
public static void main(String[] args) {
new AbsoluteLayoutExample();
}
public AbsoluteLayoutExample() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new AbsoluateLayoutManager());
JLabel test = new JLabel("Test");
add(test);
MouseAdapter ma = new MouseAdapter() {
private Point offset;
private Component dragComp;
@Override
public void mousePressed(MouseEvent e) {
Point point = e.getPoint();
for (Component comp : getComponents()) {
if (comp.getBounds().contains(point)) {
offset = new Point(point.x - comp.getX(), point.y - comp.getY());
dragComp = comp;
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
offset = null;
dragComp = null;
}
@Override
public void mouseDragged(MouseEvent e) {
if (dragComp != null) {
Point p = e.getPoint();
Point dragP = new Point(p.x - offset.x, p.y - offset.y);
dragComp.setLocation(dragP);
}
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class AbsoluateLayoutManager implements LayoutManager2 {
@Override
public void addLayoutComponent(Component comp, Object constraints) {
}
@Override
public Dimension maximumLayoutSize(Container target) {
return preferredLayoutSize(target);
}
@Override
public float getLayoutAlignmentX(Container target) {
return 0.5f;
}
@Override
public float getLayoutAlignmentY(Container target) {
return 0.5f;
}
@Override
public void invalidateLayout(Container target) {
}
@Override
public void addLayoutComponent(String name, Component comp) {
}
@Override
public void removeLayoutComponent(Component comp) {
}
@Override
public Dimension preferredLayoutSize(Container parent) {
int maxX = 0;
int maxY = 0;
for (Component comp : parent.getComponents()) {
Dimension size = comp.getPreferredSize();
maxX = Math.max(comp.getX() + size.width, maxX);
maxY = Math.max(comp.getY() + size.height, maxY);
}
return new Dimension(maxX, maxY);
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return preferredLayoutSize(parent);
}
@Override
public void layoutContainer(Container parent) {
for (Component comp : parent.getComponents()) {
Dimension size = comp.getPreferredSize();
comp.setSize(size);
}
}
}
}您还可以考虑这样的example,它是一个基于“百分比”的约束,用于布局组件,因此这些约束总是位于容器内的给定百分比点。
https://stackoverflow.com/questions/21247833
复制相似问题