I’m trying to add an Eclipse status trimbar contribution where the contents of the contribution (i.e., child elements’ text) dynamically change. Note that I’m not trying to add "line, column"
information into the status bar.
Ideally, the contribution’s width should adapt to the width of its contents, a bit like what happens in VSCode:
However, if that isn’t easily feasible, an acceptable alternative would be to have a “fixed” width for the status trimbar, or even a fixed width for each individual child (since I don’t intend to have children appearing and disappearing).
Below is what I’ve tried. How do you think I should do this if nothing I’ve tried for the past 2 days worked?
In case you think the problem might actually be an Eclipse bug, note that I’m using Eclipse version 2021-06 (4.20.0)
on Linux.
What I have tried
I have this in plugin.xml
:
<extension point="org.eclipse.ui.menus"> <menuContribution locationURI="toolbar:org.eclipse.ui.trim.status"> <toolbar id="some.package.StatusTrimBarContribution"> <control class="some.package.StatusTrimBarContribution"> </control> </toolbar> </menuContribution> </extension>
I’ve tried doing this in at least 4 different ways. As a reference, here is the class StatusTrimBarContribution
:
public class StatusTrimBarContribution extends WorkbenchWindowControlContribution { // A private static String currText = /* see below */; private Label m_lbl = null; private Label m_lbl2 = null; private Control m_root = null; public StatusTrimBarContribution() { // Register to String event } @Override public void dispose() { // Unregister from String event } @Override protected Control createControl(Composite parent) { // B } @Subscribe // From guava private void someEventHandler(String event) { currText = "lp_much_longer"; if (m_lbl != null) { m_lbl.setText(); m_root.getParent().requestLayout(); } } }
Attempt #1
In this attempt we add an intermediary Composite
between the labels and parent
, we use a GridLayout
on the intermediary, and we add a GridData
into m_lbl
.
// A private static String currText = "empty"; // B @Override protected Control createControl(Composite parent) { GridLayout gl = new GridLayout(2, false); Composite comp = new Composite(parent, SWT.NONE); comp.setLayout(gl); m_lbl = new Label(comp, SWT.RIGHT); m_lbl.setText(currText); GridDataFactory.defaultsFor(m_lbl).hint(200, SWT.DEFAULT).applyTo(m_lbl); m_lbl2 = new Label(comp, SWT.RIGHT); m_lbl2.setText("lbl2"); m_root = comp; return comp; }
The result is that the labels are too tall and get truncated. Note that I’ve also tried setting the margin height to 0, and, while it’s better than below, the labels would still get truncated.
Attempt #2
Compared to #1, we remove the intermediary Composite
, and instead use the layout directly on parent
. Also, we remove the GridData
, because, at this point, why not.
// A private static String currText = "empty"; // B @Override protected Control createControl(Composite parent) { GridLayout gl = new GridLayout(2, false); parent.setLayout(gl); m_lbl = new Label(parent, SWT.RIGHT); m_lbl.setText(currText); m_lbl2 = new Label(parent, SWT.RIGHT); m_lbl2.setText("lbl2"); m_root = m_lbl; return m_lbl; }
The result is the same as before, except, additionally, that m_lbl
is not large enough to hold the text:
Attempt #3
Compared to #2, we additionally remove the layout.
// A private static String currText = "empty"; // B @Override protected Control createControl(Composite parent) { m_lbl = new Label(parent, SWT.RIGHT); m_lbl.setText(currText); m_lbl2 = new Label(parent, SWT.RIGHT); m_lbl2.setText("lbl2"); m_root = m_lbl; return m_lbl; }
The labels are no longer too tall, however, the width of the labels is still to small for the text:
Attempt #4
Compared to #3, we initially assign a very long string into m_lbl
.
// A // Yes, this is ridiculous private static String currText = " ".repeat(60); // B @Override protected Control createControl(Composite parent) { m_lbl = new Label(parent, SWT.RIGHT); m_lbl.setText(currText); m_lbl2 = new Label(parent, SWT.RIGHT); m_lbl2.setText("lbl2"); m_root = m_lbl; return m_lbl; }
The result is that both labels are completely visible, but now m_lbl2
has the same width as m_lbl
, which is far more than I want. Plus, if the user’s font is different from mine, the width of the labels might become too large or too small due to the initial string.
Advertisement
Answer
Using the minimum width setting of GridData
works for me:
@Override protected Control createControl(final Composite parent) { final Composite comp = new Composite(parent, SWT.NONE); GridLayoutFactory.fillDefaults().numColumns(2).applyTo(comp); m_lbl = new Label(comp, SWT.RIGHT); m_lbl.setText("label 1"); GridDataFactory.fillDefaults().grab(true, false).minSize(200, SWT.DEFAULT).applyTo(m_lbl); m_lbl2 = new Label(comp, SWT.RIGHT); m_lbl2.setText("lbl2"); GridDataFactory.fillDefaults().grab(true, false).minSize(100, SWT.DEFAULT).applyTo(m_lbl2); m_root = comp; return comp; }
Note: Changing the layout of parent
is against the rules, it could damage the layout of other components.