Modify a Text inside a composite in Java SWT - java

To choose a file and save the filepath I have the following code:
case FILE :
final Composite fileBaseComposite = new Composite(table, SWT.BORDER);
fileBaseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
final GridLayout fileBaseCompositeGridLayout = new GridLayout(2, false);
fileBaseCompositeGridLayout.marginHeight = 0;
fileBaseCompositeGridLayout.marginWidth = 0;
fileBaseComposite.setLayout(fileBaseCompositeGridLayout);
final Text selectFiletext = new Text(fileBaseComposite, SWT.SINGLE);
selectFiletext.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
selectFiletext.setText(aCurrentContent);
selectFiletext.addModifyListener(new ModifyListener() {
#Override
public void modifyText(ModifyEvent e)
{
Text text = (Text)tableEditor.getEditor();
tableEditor.getItem().setText(ARGUMENT_VALUE_COLUMN, text.getText());
}
});
final Button selectFileButton = new Button(fileBaseComposite, SWT.NONE);
selectFileButton.setText("Browse");
selectFileButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
selectFileButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e)
{
FileDialog fileSelectDialog = new FileDialog(fileBaseComposite.getShell(), SWT.OPEN);
fileSelectDialog.setText("Select File");
// String is saved separately because otherwise it opens twice
String filePath = fileSelectDialog.open();
if (filePath != null) {
selectFiletext.setText(filePath);
tableEditor.getItem().setText(ARGUMENT_VALUE_COLUMN, filePath);
}
}
});
return fileBaseComposite;
when I try to modify the text manually, I've got a problem with the following error message:
java.lang.ClassCastException: org.eclipse.swt.widgets.Composite cannot be cast to org.eclipse.swt.widgets.Text
I understand the issue but cant find a solution. Is there a possibility to get the text inside the composite?
I want a text and a button in one table cell. The text should be editable manually and readable to safe it.

selectDirectoryText.addModifyListener(new ModifyListener() {
#Override
public void modifyText(ModifyEvent e)
{
Composite comp = (Composite)tableEditor.getEditor();
Text text = (Text)comp.getChildren()[0];
tableEditor.getItem().setText(ARGUMENT_VALUE_COLUMN, text.getText());
}
});
thats the solution..
I wanted to cast the Composite directly to a Text.

Related

swt menu on click hide display composites

I am building a SWT application and have a menu created. Menu has multiple menu items like Add, Edit, Help. On click of each Menu Item, I want to show a composite which will display the details of it. I am able to build it, problem I am facing is, the space of hidden composite is not taken by visible composite. How can we make the composite occupy the entire space.
Also I am adding the selection listener to make the current composite visible and other composite hidden. In the current app there will multiple menu items and each one will have composite associated it. Listener needs reference of all composites to make them visible/hidden. Is there any better approach to do this.
public class MenuToggle {
boolean startup = true;
Menu menu, fileMenu, helpMenu;
Composite composite1,composite2;
public MenuToggle(Shell shell) {
createMenu(shell);
createFileView(shell);
createHelpView(shell);
startup = false;
}
public void createMenu(Shell shell) {
//Menu Bar
menu = new Menu(shell, SWT.BAR);
//File Menu
fileMenu = new Menu(shell, SWT.DROP_DOWN);
MenuItem fileMenuHeader = new MenuItem(menu, SWT.CASCADE);
fileMenuHeader.setText("&File");
fileMenuHeader.setMenu(fileMenu);
MenuItem fileSaveItem = new MenuItem(fileMenu, SWT.PUSH);
fileSaveItem.setText("&Save");
MenuItem fileExitItem = new MenuItem(fileMenu, SWT.PUSH);
fileExitItem.setText("E&xit");
//Help Menu
helpMenu = new Menu(shell, SWT.DROP_DOWN);
MenuItem helpMenuHeader = new MenuItem(menu, SWT.CASCADE);
helpMenuHeader.setText("&Help");
helpMenuHeader.setMenu(helpMenu);
MenuItem helpGetHelpItem = new MenuItem(helpMenu, SWT.PUSH);
helpGetHelpItem.setText("&Get Help");
shell.setMenuBar(menu);
fileSaveItem.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
composite1.setVisible(true);
((GridData)composite1.getLayoutData()).exclude = false;
composite2.setVisible(false);
((GridData)composite2.getLayoutData()).exclude = true;
composite2.layout(true, true);
}
});
helpGetHelpItem.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
composite1.setVisible(false);
((GridData)composite1.getLayoutData()).exclude = true;
composite2.setVisible(true);
((GridData)composite2.getLayoutData()).exclude = false;
composite2.layout(true, true);
}
});
}
public void createFileView(Shell shell) {
composite1 = new Composite(shell, SWT.BORDER);
composite1.setVisible(true);
GridData gd1 = new GridData(SWT.FILL, SWT.FILL, true, true);
composite1.setLayoutData(gd1);
composite1.setLayout(new GridLayout(1,true));
Label label = new Label(composite1, SWT.CENTER);
label.setBounds(composite1.getClientArea());
label.setText("Saved");
}
public void createHelpView(Shell shell) {
composite2 = new Composite(shell, SWT.BORDER);
composite2.setVisible(false);
GridData gd2 = new GridData(SWT.FILL, SWT.FILL, true, true);
composite2.setLayoutData(gd2);
composite2.setLayout(new GridLayout(1,true));
Label label1 = new Label(composite2, SWT.CENTER);
label1.setBounds(composite2.getClientArea());
label1.setText("No worries!");
}
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
shell.setText("Menu Display");
MenuToggle instance = new MenuToggle(shell);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
There are a number of issues here.
You are using FillLayout for the Shell layout, so the GridData you are setting on the composites is ignored. You must use GridLayout for the Shell:
public static void main(final String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout()); // Changed
When you change the exclude settings you must call layout on the parent of the composite - the shell:
fileSaveItem.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
composite1.setVisible(true);
((GridData)composite1.getLayoutData()).exclude = false;
composite2.setVisible(false);
((GridData)composite2.getLayoutData()).exclude = true;
shell.layout(true, true); // change
}
});
helpGetHelpItem.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
composite1.setVisible(false);
((GridData)composite1.getLayoutData()).exclude = true;
composite2.setVisible(true);
((GridData)composite2.getLayoutData()).exclude = false;
shell.layout(true, true); // change
}
});
You are calling setBounds on the Label controls, this does not work when you are using layouts because the layout also calls setBounds and overrides your settings, use setLayoutData instead
Label label = new Label(composite1, SWT.CENTER);
label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // replace
//label.setBounds(composite1.getClientArea()); // wrong
As for dealing with lots of Composite controls you could call shell.getChildren and loop through the child controls. Or add the composites to a List and loop through that.

How to configure this GridLayout correctly?

I'm sadly far from being an expert in SWT and RCP, but I really tried my best here... I can't figure out how to configure the widgets to get this layout (just a Photoshopped screen, never worked this way):
This is what I get if I set the column number of the GridLayout to 2:
Here is the Refresh and the Blacklist button in the wrong row, but at least everything is visible...
And this is what I get if I set the column number of the GridLayout to 3:
This is total messed up... Most of the widgets are pushed outside the visible area. DatePicker, Refresh, Whitelist and the Calculate buttons are not visible, they are somewhere outside on the right.
This is the codepart for this screen area:
resultingProductsGroup = new Group(propProdGroup, SWT.NONE);
final GridData gd_resultingProductsGroup = new GridData(SWT.FILL,
SWT.CENTER, true, false);
gd_resultingProductsGroup.widthHint = 240;
resultingProductsGroup.setLayoutData(gd_resultingProductsGroup);
resultingProductsGroup.setText("Resulting products");
final GridLayout gridLayout_4 = new GridLayout();
gridLayout_4.numColumns = 2;
resultingProductsGroup.setLayout(gridLayout_4);
Label refDateLabel = new Label(resultingProductsGroup, SWT.NONE);
refDateLabel.setText("Reference date:");
refDateInput = new DateInput(resultingProductsGroup, SWT.BORDER);
refDateInput.setLayoutData(new GridData());
refDateInput.setValue(new Date());
calculateProductsButton1 = new Button(resultingProductsGroup, SWT.NONE);
setupImageButton(calculateProductsButton1, Images.getButtonRefresh());
calculateProductsButton1.setLayoutData(new GridData());
GridDataFactory.swtDefaults().hint(18, 18).applyTo(
calculateProductsButton1);
resultingProductsTable = new TableListWidget<Product>(
resultingProductsGroup, SWT.BORDER, ListWidgetMode.MULTI);
resultingProductsTable.setLinesVisible(true);
resultingProductsTable.setHeaderVisible(true);
final GridData rpTableProperty = new GridData(SWT.FILL, SWT.FILL, true,
true, 3, 1);
resultingProductsTable.setLayoutData(rpTableProperty);
GridDataFactory.swtDefaults().hint(230, 240).applyTo(
resultingProductsTable);
setupResultingProductsTableColumns();
resultingProductsTable.sortByComparator(new Comparator<Product>() {
#Override
public int compare(Product o1, Product o2) {
return o1.getPartNum().getExternalId().compareTo(
o2.getPartNum().getExternalId());
}
});
resultingProductsTable.addOpenListener(new IOpenListener() {
#Override
public void open(OpenEvent event) {
doResultingProductsTableOpen();
}
});
calculateProductsButton2 = new Button(resultingProductsGroup, SWT.NONE);
calculateProductsButton2.setText("Calculate");
whitelistAddButton = new Button(resultingProductsGroup, SWT.NONE);
whitelistAddButton.setText("Whitelist");
whitelistAddButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
doAddToWhitelist();
}
});
blacklistAddButton = new Button(resultingProductsGroup, SWT.NONE);
blacklistAddButton.setText("Blacklist");
blacklistAddButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
doAddToBlacklist();
}
});
What am I not seeing here? I'm stuck with this GUI bug for over 2 days now... Please, help me :)
You could design the whole composite with one GridLayout and 3 columns, while using horizontal span of 3 on the table. That doesn't give you the desired mocked up screen though, because reference date controls and buttons at the bottom would be aligned in columns.
Try instead using 3 composites
reference date: row layout
table: fill layout
button list: row layout

How to scroll a scrolled composite using mouse wheels in SWT

I would like to know if it is possible to scroll a ScrolledCompositeusing mouse wheels. By default it is not working.
Apparently, it is necessary to create mouse wheel listener for your composite. You can use something like this as the basis:
scrolledComposite = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
GridData scrollGridData = new GridData(SWT.FILL, SWT.FILL, true, true);
scrolledComposite.setLayoutData(scrollGridData);
layout = new GridLayout();
scrolledComposite.setLayout(layout);
compositeWrapper = new Composite(scrolledComposite);
compositeWrapper.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
compositeWrapper.setLayout(layout);
scrolledComposite.setExpandHorizontal(true);
scrolledComposite.setExpandVertical(true);
scrolledComposite.addListener(SWT.MouseWheel, new Listener() {
public void handleEvent(Event event) {
int wheelCount = event.count;
wheelCount = (int) Math.ceil(wheelCount / 3.0f);
while (wheelCount < 0) {
scrolledComposite.getVerticalBar().setIncrement(4);
wheelCount++;
}
while (wheelCount > 0) {
scrolledComposite.getVerticalBar().setIncrement(-4);
wheelCount--;
}
}
});
I'm not sure why #AlexanderGavrilov is writing so much code, the following works for me as well:
scrolledComposite.addListener(SWT.MouseWheel, new Listener() {
public void handleEvent(Event event) {
scrolledComposite.getVerticalBar().setIncrement(e.count*3);
}
});
After googling around, I found a simple solution,
scrolledComposite.addListener(SWT.Activate, new Listener() {
public void handleEvent(Event e) {
scrolledComposite.setFocus();
}
});

About dialog for html page in SWT application

I have an about dialog in Swing that uses a JEditorPane to display an html document (setContentType("text/html");).
I want to creat an about dialog in an Eclipse SWT application and display this same html document which will be displayed formatted (hyperlinks, br etc) same as it did in Swing.
How could I do this? What is the appropriate widget? StyledText?
I started with a Browser in a Handler:
#Execute
public void execute(final Shell currentShell){
//load html file in textReader
Browser browser = new Browser(currentShell, SWT.NONE);
browser.setText(textReader.toString());
}
But nothing is displayed. What is the proper way to resolve this?
Update: Tested #Baz change:
#Execute
public void execute(final Shell currentShell){
currentShell.setLayout(new FillLayout());
//load html file in textReader
Browser browser = new Browser(currentShell, SWT.NONE);
browser.setText(textReader.toString());
currentShell.pack();
}
It completelly ruins the application! The html is loaded covering the existing elements
You can always use the good old JFace Dialog with an embedded Browser widget:
public class BrowserDialog extends Dialog {
private String browserString;
protected BrowserDialog(Shell parentShell, String browserString) {
super(parentShell);
this.browserString = browserString;
}
#Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
GridLayout layout = new GridLayout(1, false);
composite.setLayout(layout);
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.widthHint = 400;
data.heightHint = 400;
composite.setLayoutData(data);
Browser browser = new Browser(composite, SWT.NONE);
browser.setText(browserString);
browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
return composite;
}
#Override
protected void createButtonsForButtonBar(Composite parent) {
}
#Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText("About");
}
#Override
public void okPressed() {
close();
}
public static void main(String[] args)
{
final Display display = new Display();
Shell shell = new Shell(display);
Color gray = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
String hex = String.format("#%02x%02x%02x", gray.getRed(), gray.getGreen(), gray.getBlue());
new BrowserDialog(shell, "<body bgcolor='" + hex + "'><h2>TEXT</h2></body>").open();
}
}
Looks like this:
If you want the dialog buttons, just replace the createButtonsForButtonBar(Composite parent) method with this:
#Override
protected void createButtonsForButtonBar(Composite parent) {
createButton(parent, Dialog.OK, "OK", true);
createButton(parent, Dialog.CANCEL, "Cancel", false);
}
Then it will look like this:

SWT composite - redraw problem

I have a composite element, that initially has a Label. Now I call dispose on the it (the label) and create another label in the same container (composite elm), but I don't see the new text. It brings me to question how do I enable redraw on the composite, so that the new label (or any other component I might create) will render in place of the old one.
Here is the code I have (separated into a unit test for redraw a composite)
private Label createLabel( Composite parent) {
Label label = new Label(parent, SWT.NONE);
label.setAlignment(SWT.CENTER);
label.setLayoutData( new GridData( SWT.CENTER, SWT.CENTER, true, true) );
return label;
}
private void changeText() {
assert testCell != null : "Please initialize test cell";
testCell.getChildren()[0].dispose();
Label l = createLabel(testCell);
l.setText("New TexT");
testCell.redraw();
}
private void draw() {
Display display = new Display();
shell = new Shell(display);
shell.setLayout(new GridLayout(2,false));
testCell = new Composite(shell,SWT.BORDER);
testCell.setLayout(new GridLayout());
Label l = createLabel(testCell);
l.setText("Old Text");
Composite btnCell = new Composite(shell,SWT.NONE);
btnCell.setLayout(new GridLayout());
Button b = new Button(btnCell, SWT.PUSH);
b.setText("Change");
b.addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event e) {
changeText();
}
});
As you can see, I am calling redraw on the composite after I add a new element. Also, I have verified that after the call to dispose, testCell.getChildren().length returns 0, as expected, and when I create a new label, I get the same expression to return 1, verifying that the new element is indeed getting added to its parent composite container
Am I missing something here ?
In the changeText() function, the
testCell.redraw();
line should be replaced by
testCell.layout();
Or, if you want to resize it correctly you should use
shell.layout();.
I would say add a selectionListener on the label.
.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
//Change text by Label.setText();
}
}

Categories

Resources