Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
How to combine button and text field using SWT and also give a customized icon for the button.
Many have suggested to use Combo but it gives drop down option, but I don't want it to be a drop down icon. Can any one help here and suggest an implementation strategy?
If I understand your question correctly, then the best approach would be to use a Composite to group Text and Label objects.
The Text object is obviously your text field, and with the Label you can set an image to give a nice border-less button.
Depending on your needs, this can be easily extended to allow for a multi-line text area, but I'll stick with a single line for the example
public class TextWithButtonExample {
/**
* Simple class to accomplish what you want by wrapping
* the Text and Label objects with a Composite.
*/
public class TextWithButton {
public TextWithButton(final Composite parent) {
// The border gives the appearance of a single component
final Composite baseComposite = new Composite(parent, SWT.BORDER);
baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
final GridLayout baseCompositeGridLayout = new GridLayout(2, false);
baseCompositeGridLayout.marginHeight = 0;
baseCompositeGridLayout.marginWidth = 0;
baseComposite.setLayout(baseCompositeGridLayout);
// You can set the background color and force it on
// the children (the Text and Label objects) to add
// to the illusion of a single component
baseComposite.setBackground(new Color(parent.getDisplay(), new RGB(255, 255, 255)));
baseComposite.setBackgroundMode(SWT.INHERIT_FORCE);
final Text text = new Text(baseComposite, SWT.SINGLE);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// Get whatever image you want from wherever
// (in this case the web so it can be run easily!)
Image buttonImage;
try {
buttonImage = ImageDescriptor.createFromURL(new URL("http://eclipse-icons.i24.cc/ovr16/clear.gif")).createImage();
} catch (final MalformedURLException e) {
buttonImage = null;
}
final Label button = new Label(baseComposite, SWT.NONE);
button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
button.setImage(buttonImage);
button.addMouseListener(new MouseAdapter() {
#Override
public void mouseUp(final MouseEvent e) {
// Do whatever you want when the 'button' is clicked
text.setText("");
}
});
}
}
final Display display;
final Shell shell;
public TextWithButtonExample() {
display = new Display();
shell = new Shell(display);
shell.setLayout(new GridLayout());
shell.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
new TextWithButton(shell);
}
public void run() {
shell.setSize(200, 100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
public static void main(final String[] args) {
new TextWithButtonExample().run();
}
}
Related
I want to get the control the mouse hovers over which normally is done by Display#getCursorControl. However when one control in the hierarchy is disabled, this method doesn't work any longer:
Example:
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setSize(400, 300);
shell.setLayout(new GridLayout(2, false));
final Label mouseControl = new Label(shell, SWT.BORDER);
mouseControl.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).grab(true, true).create());
display.addFilter(SWT.MouseMove,
e -> mouseControl.setText("" + e.display.getCursorControl()));
final Group enabledGroup = new Group(shell, SWT.NONE);
enabledGroup.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
enabledGroup.setText("Enabled Group");
createControls(enabledGroup);
final Group disabledGroup = new Group(shell, SWT.NONE);
disabledGroup.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
disabledGroup.setText("Disabled Group");
disabledGroup.setEnabled(false);
createControls(disabledGroup);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
private static void createControls(Composite parent) {
parent.setLayout(new GridLayout());
final Label label = new Label(parent, SWT.NONE);
label.setText("Label");
final Text text = new Text(parent, SWT.BORDER);
text.setText("Text");
}
Hold the mouse over the left label and then over the right one. The control is only displayed for an enabled parent, else the shell is displayed.
How do I get the control below the mouse pointer? Do I have to implement this functionality myself? Are there any methods that can help me or do I have to calculate the bounds of each control inside the tree and check if it is on the mouse position?
I can't see anything in Display that would help.
The following will search the children of a Shell for a control containing the cursor and works with disabled controls:
static Control findCursorinShellChildren(final Shell shell)
{
return findLocationInCompositeChildren(shell, shell.getDisplay().getCursorLocation());
}
static Control findLocationInCompositeChildren(final Composite composite, final Point displayLoc)
{
final var compositeRelativeLoc = composite.toControl(displayLoc);
for (final var child : composite.getChildren())
{
if (child.getBounds().contains(compositeRelativeLoc))
{
if (child instanceof Composite)
{
final var containedControl = findLocationInCompositeChildren((Composite)child, displayLoc);
return containedControl != null ? containedControl : child;
}
return child;
}
}
return null;
}
I imagine this is going to be significantly slower than Display.getCursorControl
I am using Java's SWT toolkit to create a GUI with text field inputs. These input fields require numerical input and have units assigned to them. I'm trying to create a fancy way to integrate units within the field as a fixed suffix to the text, such that the user can only edit the numerical part. I'd also like for the suffix to be greyed out so the user knows it is disabled - something like the following:
While searching, I saw some solutions with a mask formatter from Swing that might do the trick, but I'm sort of hoping there might be something default with SWT. Any suggestions on how to make this work?
The field is part of a a matrix, so I can't simply add the units to a header label. I suppose I could create another column after the text field that could provide units as a label, but I'm going for something more intuitive and aesthetic.
Any suggestions?
One option would be to group Text and Label widgets in the same composite, and set the text on the Label to the desired suffix:
The area to the left of the suffix is the single-line text field, which can be edited, and the suffix is a disabled Label.
public class TextWithSuffixExample {
public class TextWithSuffix {
public TextWithSuffix(final Composite parent) {
// The border gives the appearance of a single component
final Composite baseComposite = new Composite(parent, SWT.BORDER);
baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
final GridLayout baseCompositeGridLayout = new GridLayout(2, false);
baseCompositeGridLayout.marginHeight = 0;
baseCompositeGridLayout.marginWidth = 0;
baseComposite.setLayout(baseCompositeGridLayout);
// You can set the background color and force it on
// the children (the Text and Label objects) to add
// to the illusion of a single component
baseComposite.setBackground(new Color(parent.getDisplay(), new RGB(255, 255, 255)));
baseComposite.setBackgroundMode(SWT.INHERIT_FORCE);
final Text text = new Text(baseComposite, SWT.SINGLE | SWT.RIGHT);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Label label = new Label(baseComposite, SWT.NONE);
label.setEnabled(false);
label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true));
label.setText("kg/m^3");
}
}
final Display display;
final Shell shell;
public TextWithSuffixExample() {
display = new Display();
shell = new Shell(display);
shell.setLayout(new GridLayout());
shell.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
new TextWithSuffix(shell);
}
public void run() {
shell.setSize(200, 100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
public static void main(final String[] args) {
new TextWithSuffixExample().run();
}
}
I have a ScrolledComposite widget that I'm initializing inside a selection listener (in turn attached to another composite). This ScrolledComposite contains in turn another Composite, which in turn holds a Button and a Label. While the internal composite appears, none of its children widgets do. I've used ScrolledComposite plenty of times before, and everything looks right to my eye. Can any of you see anything wrong? Note, the ScrolledComposite is a class variable. Also note that this problem is occurring regardless of if I ever dispose of the composite and its contents in the else condition.
final Button showConsole = new Button(topLeft, SWT.CHECK);
showConsole.setText("Show Debug Console");
showConsole.setFont(new Font(domains.getDisplay(), "Segoe UI", 9, SWT.ITALIC));
showConsole.setSelection(false);
showConsole.addSelectionListener(new SelectionListener() {
#Override
public void widgetSelected(SelectionEvent e) {
//The total widget group is only supposed to appear when the button is selected
if (showConsole.getSelection()) {
scrolledConsoleComp = new ScrolledComposite(leftComposite,
SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
Composite consoleComposite = new ScrolledComposite(scrolledConsoleComp, SWT.NONE | SWT.BORDER);
consoleComposite.setLayout(new GridLayout());
consoleComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
consoleComposite.setVisible(true);
scrolledConsoleComp.setContent(consoleComposite);
scrolledConsoleComp.setExpandHorizontal(true);
scrolledConsoleComp.setExpandVertical(true);
scrolledConsoleComp.setLayout(new GridLayout());
scrolledConsoleComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Button clear = new Button(consoleComposite, SWT.PUSH);
clear.setText("Clear Console");
final Label consoleText = new Label(consoleComposite, SWT.WRAP);
consoleText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
consoleText.setText("Messages: \n" + consoleData);
clear.addSelectionListener(new SelectionListener() {
#Override
public void widgetSelected(SelectionEvent e) {
consoleData = "";
consoleText.setText("Messages: \n" + consoleData);
}
#Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
scrolledConsoleComp.setMinSize(leftComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
leftComposite.layout(true);
} else {
scrolledConsoleComp.setVisible(false);
scrolledConsoleComp.dispose();
leftComposite.layout(true);
}
}
I appreciate any insight. Let me know if anything in this question is unclear. Thank you!
You're creating your Button and your Label inside a ScrolledComposite. They won't be shown because setContent() is not called.
Usually a ScrolledComposite contains a Composite that holds all the other Widgets.
Your consoleComposite should become a Composite.
No need for a call to setVisible()
I have little problem with StyledText. When I use setText() Method and text is long, I must wait few seconds for render that text. Is there any method what can I use to speed up showing this text?
The only optimisation you can implement is putting your setText() in a Job or in a Runnable to not block the UI.
Other than that, it's an API limitation from SWT.
Other suggestions:
File a bug/feature request
Search for a StyledText, although apparently none exist
Rethink your program. Don't you have a backup plan? Is the performance critical?
Edit:
#greg-449
/**
*
* #author ggrec
*
*/
public class Test
{
public static void main(final String[] args)
{
new Test();
}
private Test()
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout(1, false));
final Button button = new Button(shell, SWT.PUSH);
button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
button.setText("Press me");
final StyledText text = new StyledText(shell, SWT.NONE);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
button.addSelectionListener(new SelectionAdapter()
{
#Override public void widgetSelected(final SelectionEvent e)
{
Display.getDefault().asyncExec(new Runnable()
{
#Override public void run()
{
text.setText("*put very long text here*");
}
});
}
});
shell.setSize(1000, 1000);
shell.open();
while (!shell.isDisposed())
{
if ( !display.readAndDispatch() )
display.sleep();
}
display.dispose();
}
}
i am new to swt and im trying to create a layout in a window. Each texfield will have a label to the left of the textfield- however in some cases there may be two textfields per label, and maybe at a later date there will be radio buttons added. Is a formlayout the best way of doing this? It seems to me unnecessarily over-complicated. I dont have windowbuilder or a visual designer utility and am finding the FormAttachment method difficult to handle. Any advice appreciated. I have attached a screenshot of the basic gui design Im trying to create.
Unfortunately im not allowed upload images for the moment, as i a new user. Essentially the structure i am aiming for is like so:
LABEL TEXTBOX
LABEL TEXTBOX TEXTBOX
LABEL TEXTBOX
LABEL TEXTBOX TEXTBOX
LABEL CALENDAR CONTROL
OK | NOK
Here is a simple example that should explain how to span a widget across multiple columns of a GridLayout:
public class StackOverflow2
{
public static void main(String[] args)
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new GridLayout(3, false));
Label firstLabel = new Label(shell, SWT.NONE);
firstLabel.setText("Label");
Text firstText = new Text(shell, SWT.BORDER);
addSpanData(firstText, 2);
Label secondLabel = new Label(shell, SWT.NONE);
secondLabel.setText("Label");
Text secondText = new Text(shell, SWT.BORDER);
addSpanData(secondText, 1);
Text thirdText = new Text(shell, SWT.BORDER);
addSpanData(thirdText, 1);
Label thirdLabel = new Label(shell, SWT.NONE);
thirdLabel.setText("Label");
Text fourthText = new Text(shell, SWT.BORDER);
addSpanData(fourthText, 2);
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
private static void addSpanData(Control comp, int span)
{
GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
data.horizontalSpan = span;
comp.setLayoutData(data);
}
}
This is how it looks: