不使用JLayeredPane将jcomponent移到后面



我写了一个DragAndDrop MouseListener。

组分A是";背景";组件B后面的图像。两者都位于JPanel上。

我已使图像可拖动。然而,我希望图像在拖动时保持在组件B后面

然而,每次我拖动图像时,我想Java都会给它聚焦或其他什么,所以它会被带到最前面。

有没有一种方法可以在我拖动图像时将其保留在后面?

我知道每次拖动时都可以使用JLayeredPanemoveToBack方法,但我宁愿不使用JLayeredPane,只使用JPanel。JPanel有moveToBack等价物吗?

或者有没有一种方法可以让组件保留当前层(可能"不获得焦点"(,这样我就可以在其当前层中拖动它?

这是一个的例子

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class OverlapTester extends JFrame {
public static final long serialVersionUID = 172L;

public static void main(String[] args) {


OverlapTester frame = new OverlapTester();

frame.initialize();

}
public void initialize() {
setLayout(null);

JButton bottom = new JButton("bottom");
JButton top = new JButton("top");
bottom.setBounds(0,0,100,100);
top.setBounds(0,0,50,50);

add(top);
add(bottom);

int bottomZOrder = 0;

bottom.addMouseListener(new MouseListener(){
@Override
public void mouseEntered(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
@Override
public void mouseExited(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
@Override
public void mouseReleased(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
@Override
public void mousePressed(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
@Override
public void mouseClicked(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
});

bottom.addMouseMotionListener(new MouseMotionListener(){
@Override
public void mouseDragged(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}

@Override
public void mouseMoved(MouseEvent e) { 
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
});

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setExtendedState(MAXIMIZED_BOTH);
setVisible(true);
}


}

组件A是一个"背景";组件B后面的图像。两者都位于JPanel上。

Swing组件是基于它们的ZOrder绘制的。首先绘制最高的ZOrder

ZOrder被指定为添加到面板中的组件。因此,添加的第一个分量被赋予ZOrder 0,第二个分量被给予ZOrder 1

所以添加您的";背景";图像到面板的最后一个,它将始终具有最高的ZOrder,这意味着它首先被绘制,所以其他组件将被绘制在它的顶部。

例如:

panel.add(someOtherComponent);
panel.add(background);

或者您可以使用:

Container.setComponentZOrder(...)

在添加组件之后动态地改变CCD_ 10的方法。

编辑:

我提供的答案是,你是一个非此即彼的解决方案。你只需要选择一种方法。

  1. 您正确地实现了第一种方法,即添加"背景";组件最后。所以没有必要玩ZOrder。当ZOrder保持固定时,这种方法非常有效。

  2. 第二种方法是当您希望ZOrder动态更改时,例如当您有多个组件,并且您希望在与每个组件交互时更改它时。然而,您错误地实施了这种方法。您使用了";0";对于ZOrder,这意味着该组件将始终绘制在最后,因此位于任何其他组件的顶部。

在当前示例中,不需要动态更改ZOrder,因此可以删除所有相关代码。

正如你所看到的,底部按钮一直被添加到最前面的

Swing绘画经过优化,可以假设组件不重叠。

但是,在JButton的情况下,当您将鼠标悬停在按钮上以重新绘制Border时,它具有自动重新绘制逻辑。因此,当按钮被重新绘制时,它仍然会在其他组件的顶部绘制。

所以你需要告诉Swing不要优化绘画。因此,当一个组件被重新绘制时,当它们重叠时,所有组件都将被重新绘制。您可以通过覆盖isOptimizedDrawingEnabled(...)方法来实现这一点,如下所示:

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JButton;
import javax.swing.*;
public class OverlapTester extends JFrame {
public static void main(String[] args) {
OverlapTester frame = new OverlapTester();
frame.initialize();
}
public void initialize() {
JPanel contentPane = new JPanel(null)
{
@Override
public boolean isOptimizedDrawingEnabled()
{
return false;
}
};
add(contentPane);
//    setLayout(null);
JButton bottom = new JButton("bottom");
JButton top = new JButton("top");
bottom.setBounds(0,0,100,100);
top.setBounds(0,0,50,50);
//    add(top);
//    add(bottom);
contentPane.add(top);
contentPane.add(bottom);
//    int bottomZOrder = 0;
int bottomZOrder = 1;

bottom.addMouseListener(new MouseListener(){
@Override
public void mouseEntered(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
@Override
public void mouseExited(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
@Override
public void mouseReleased(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
@Override
public void mousePressed(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
@Override
public void mouseClicked(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
});
bottom.addMouseMotionListener(new MouseMotionListener(){
@Override
public void mouseDragged(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
@Override
public void mouseMoved(MouseEvent e) {
e.getComponent().getParent().setComponentZOrder(e.getComponent(), bottomZOrder);
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setExtendedState(MAXIMIZED_BOTH);
setVisible(true);
}

}

最新更新