【问题标题】:How to NOT extend Swing components?如何不扩展 Swing 组件?
【发布时间】: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

标签: java swing oop


【解决方案1】:

我可以用鼠标重新定位组件:

然后您只需将MouseListener/MouseMotionListener 添加到您要拖动的组件中。无需扩展任何组件即可添加该功能。

查看Component Mover 类,了解对组件进行基本拖动以及更复杂的拖动解决方案的示例。

【讨论】:

  • 哇,你说得对。我没有那样想过。确实没有必要将此功能绑定到任何特定的容器类型,如果不是,它会更加灵活。 ComponentMover 很好地展示了这一点。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
  • 2023-01-12
  • 2019-03-28
  • 2012-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多