【发布时间】:2017-04-30 15:53:22
【问题描述】:
我看到许多发帖人认为不应扩展 Swing 组件,而应通过组合添加功能。所以说我想以绝对定位(无布局管理器)可重用地创建一个JPanel,我可以在其中用鼠标重新定位组件:
public class MoveableComponentPanel
{
private final JPanel m_panel;
public MoveableComponentPanel()
{
m_panel = new JPanel(null);
}
public void add(Component c)
{
m_panel.add(c);
c.addMouseListener(m_mover);
c.setSize(c.getPreferredSize());
}
private final MouseListener m_mover = new MouseListener()
{
private int m_startX, m_startY;
@Override
public void mousePressed(MouseEvent e)
{
if (e.getButton() == MouseEvent.BUTTON1)
{
m_startX = e.getX();
m_startY = e.getY();
}
}
@Override
public void mouseReleased(MouseEvent e)
{
if (e.getButton() == MouseEvent.BUTTON1)
{
Component c = e.getComponent();
Point p = c.getLocation();
p.x += e.getX() - m_startX;
p.y += e.getY() - m_startY;
c.setLocation(p);
c.repaint();
}
}
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
};
}
看起来不错,但无法将面板添加到容器中。如果我想允许调用类与面板交互,则更令人头疼,例如更改大小、背景颜色、注册事件侦听器等。要么添加一个 getPanel() 访问器,它会破坏封装,要么为我想要公开的 JPanel 方法/属性编写传递方法(可能很多)。我在这里还缺少其他策略吗?公认的最佳做法是什么?
【问题讨论】:
-
我认为在这里扩展
JPanel没有任何问题... -
“我看到很多张贴者认为 Swing 组件不应该被扩展。” 作为一个经常给出这个建议的人,我会指出这是一条“一般规则”,而不是刻在石头上的规则。有 种有效情况下扩展组件是有意义的(例如自定义绘画)。 “..绝对定位(无布局管理器),我可以用鼠标重新定位组件” ..为什么?我希望这不是试图制作“GUI 设计师”的尝试,因为由此产生的 GUI 将具有通常对没有布局的 GUI 造成的所有问题。 ..
-
.. 但如果它真的是一个 D'n'D 面板的好案例,我强烈建议实施一个
DragAndDropLayout,因为这至少会让你考虑一些可能会出错的事情。 -
这是一个基于Reflection的UML类图查看器。
-
扩展
JPanel为您提供 UI 委托并让您管理 preferred size。另见JHotDraw,引用here。