垂直视图中的可拖动组件 (Java Swing)
Posted
技术标签:
【中文标题】垂直视图中的可拖动组件 (Java Swing)【英文标题】:DraggableComponents in vertical view (Java Swing) 【发布时间】:2020-04-05 17:02:18 【问题描述】:这是我在这个平台上的第一个问题,请耐心等待:
我正在使用 Java Swing 制作一个 LayerPanel,就像在 Photoshop 中一样,LayerPanel 的每个子项也是一个代表一个图层的面板。就像在 Photoshop 中一样,我使用鼠标移动 LayerPanel 的这些子项,使用 DraggableComponent 类的灵感来自:输入图像描述 heregable-component>。
问题在于重新排列 UI 中的图层。我无法在 UI 中切换面板。
这是我目前的代码:
可拖动组件:
class DraggableComponent extends JPanel implements MouseListener, MouseMotionListener
private LayerPanel panel;
private volatile int screenY = 0;
private volatile int myY = 0;
private String name;
public DraggableComponent(LayerPanel panel, String name)
setPreferredSize(new Dimension(300, 80));
this.name = name;
this.panel = panel;
updateBorder(name);
setVisible(true);
setLayout(null);
addMouseListener(this);
addMouseMotionListener(this);
private void updateBorder(String name)
setBorder(new TitledBorder(new DropShadowBorder(), name, TitledBorder.LEADING, TitledBorder.BELOW_TOP, null, null));
private void handleLocation(int y)
if (y >= getParent().getHeight() - this.getHeight())
setLocation(getLocation().x, getParent().getHeight() - this.getHeight());
else setLocation(getLocation().x, Math.max(y, 0));
@Override
public void mousePressed(MouseEvent e)
screenY = e.getYOnScreen();
myY = getY();
@Override
public void mouseReleased(MouseEvent e)
panel.handleReleased(this);
@Override
public void mouseDragged(MouseEvent e)
int deltaY = e.getYOnScreen() - screenY;
handleLocation(myY + deltaY);
panel.handleLocation(this);
public void rename(String name)
this.name = name;
updateBorder(name);
LayerPanel 类:
public class LayerPanel extends JPanel
private ArrayList<DraggableComponent> components = new ArrayList<>();
protected int HEIGHT_PER_COMPONENT;
public LayerPanel(int height, int amountOfComponents)
setPreferredSize(new Dimension(200, height));
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
for (int i = 0; i < 10; i++)
components.add(new DraggableComponent(this, Integer.toString(i)));
updateComponents();
public void addComponent(String name)
components.add(new DraggableComponent(this, name));
updateComponents();
private void updateComponents()
HEIGHT_PER_COMPONENT = getHeight() / (components.size() + 1);
removeAll();
for (DraggableComponent c : components)
//c.rename(Integer.toString(components.indexOf(c)));
add(c);
c.setLocation(0, HEIGHT_PER_COMPONENT * components.indexOf(c));
public void handleReleased(DraggableComponent component)
updateComponents();
public void handleLocation(DraggableComponent component)
final int index = components.indexOf(component);
for (DraggableComponent nextComponent : components)
final int indexNext = components.indexOf(nextComponent);
if (component.getY() >= nextComponent.getY() - HEIGHT_PER_COMPONENT / 2 && !component.equals(nextComponent))
Collections.swap(components, indexNext, indexNext - 1);
updateComponents();
public static void main(String[] args)
JFrame f = new JFrame("Layers test");
LayerPanel panel = new LayerPanel(800, 10);
f.add(panel);
f.setSize(300, 800);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
【问题讨论】:
【参考方案1】:问题在于重新排列图层。
无需自己管理。
这由面板中组件的ZOrder
控制。
在您的mousePressed
事件中,您可以将组件的ZOrder
设置为0,以确保该组件最后绘制,这意味着它现在将绘制面板上所有其他组件的顶部。
类似:
Container container = e.getComponent().getParent();
container.setComponentZOrder(e.getComponent(), 0);
【讨论】:
这实际上有助于解决我将要遇到的第二个问题,但我的问题在于 UI 而不是实际绘图。我的意思是用鼠标重新排列 UI 元素。它们仍然符合布局。修复后,我必须实现这一点。感谢您回复@camickr(编辑:我会在此页面的问题部分更好地指定)以上是关于垂直视图中的可拖动组件 (Java Swing)的主要内容,如果未能解决你的问题,请参考以下文章
使用 UIPanGestureRecognizer 的可拖动视图中的操作元素导致视图移动
java swing JPanel添加在JScrollPane上,有垂直的滚动条,可是滚动条拉到底,只显示了JPanel的一部分。