当桥的内容发生变化时,刷新包含AWT-SWT桥的Eclipse RCP部件

时间:2017-05-25 04:16:38

标签: java eclipse rcp e4 swt-awt

我正在处理一个从Swing版本过渡的RCP应用程序。因此,在此过渡期间,我们有许多UI组件仍需要存在于Swing世界中。我能够将现有的Swing组件正确放置在AWT-SWT桥接框架中。

我将这些Swing组件包装在JScrollable窗格中,然后再将它们添加到桥中,这样当Swing UI元素的大小发生变化时,我就不必调整包含部分的大小。我在部件中放置旧Swing组件的代码如下所示:

@PostConstruct
public void postConstruct(final Composite parent) {

    /* Create embedding composite */
    final Frame bridgeFrame;
    final Composite embed;
    embed = new Composite(parent, SWT.EMBEDDED);
    embed.setLayout(new FillLayout());
    bridgeFrame = SWT_AWT.new_Frame(embed);
    bridgeFrame.setLayout(new BorderLayout());
    bridgeFrame.add(
            new JScrollPane(getTestPanel()),
            BorderLayout.CENTER);
}

我的Swing组件有一种行为,当用户单击按钮时,组件中隐藏的内容可见,或者新的UI元素添加到Swing组件。例如:

private JPanel getTestPanel() {
    final JPanel output;
    final JButton eastBttn, westBttn;
    output = new JPanel();
    eastBttn = new JButton("East Button");
    westBttn = new JButton("West Button");
    output.setLayout(new BorderLayout());
    output.add(eastBttn, BorderLayout.EAST);
    output.add(westBttn, BorderLayout.WEST);

    eastBttn.addActionListener(evt -> {
        System.out.println("East Button Clicked");
        output.add(new JLabel("East Button Clicked"), BorderLayout.CENTER);
    });

    return output;
}

我的问题是,当Swing组件中的元素发生更改时,父桥接框架无法正确呈现。

首次创建部件时,我的应用程序如下所示: before

点击EastButton后,它应该在该桥架的中心添加一个文本标签。但是,在应用程序视图中没有任何变化。

但是,当我甚至开始调整包含部分窗扇的大小时,包含桥架的部分会正确更新:after resizing

如何自动更新包含部件更新的桥接框架?

为了测试这是否是桥架上的重新绘制问题,我有一个菜单项会触发桥架的repaint / revalidate / pack,但是没有解决问题。我怀疑它与包含部分的渲染器有关,但不知道如何解决它。

2 个答案:

答案 0 :(得分:1)

纯Swing解决方案中存在同样的问题:

public static void main(String[] args) {
    JFrame bridgeFrame = new JFrame("Test");
    bridgeFrame.setSize(400, 400);
    bridgeFrame.setLayout(new BorderLayout());
    bridgeFrame.add(new JScrollPane(getTestPanel()), BorderLayout.CENTER);

    bridgeFrame.setVisible(true);
}

您需要在事件处理程序中添加output.doLayout()

答案 1 :(得分:0)

我最终通过将自定义ControlListener / ComponentListener附加到包含网桥的部分来解决问题。如果桥接框架的工作中的任何更改导致它调整到超出父级,我会让侦听器调整它以适应父级,从而强制滚动窗格接管。

这是我的听众:

public class BridgeComponetAdapter
        extends ComponentAdapter
        implements ControlListener {

    private final Composite parent;
    private final Frame bridgeFrame;
    private Point parentSize;

    public BridgeComponetAdapter(
            final Composite parent,
            final Frame bridgeFrame) {
        this.parent = parent;
        this.bridgeFrame = bridgeFrame;
        bridgeFrame.addComponentListener(this);
        parent.addControlListener(this);
    }

    @Override
    public void componentResized(final ComponentEvent e) {
        System.out.println(e);
        if (e.getSource() != bridgeFrame)
            return;

        final Dimension currentBridgeSize;
        currentBridgeSize = bridgeFrame.getSize();
        if (currentBridgeSize.getWidth() > parentSize.x
                || currentBridgeSize.getHeight() > parentSize.y) {
            bridgeFrame.setSize(parentSize.x, parentSize.y);
        }
    }

    @Override
    public void controlMoved(final ControlEvent e) {}

    @Override
    public void controlResized(final ControlEvent e) {
        System.out.println(e);
        if (e.getSource() == parent)
            parentSize = parent.getSize();
    }
}

这不是一个优雅的解决方案;我仍然愿意接受其他想法来解决问题。