I want to use the JFace PopupDialog as lightweight dialog for user input. But I have some problems with the background color of text widgets.
As you can see below in 1, a SWT.MULTI text widget has no background and border, a SWT.SINGLE text widget has no background.
I tried to override the background color with:
Text comment = new Text(composite, SWT.MULTI|SWT.BORDER);
comment.setFocus();
comment.setBackground(new Color(Display.getDefault(), new RGB(000, 000, 000)));
// method of PopupDialog
applyBackgroundColor(new Color(Display.getDefault(), new RGB(000, 000, 000)), comment);
Does anybody has any idea how to handle this properly?
Thanks in advance!
EDIT: As requested, here is the source for the popup. I subclassed the PopupDialog, as I wanted the popup to be opened next to the Cursor location:
public class MouseLocationPopupDialog extends PopupDialog {
private final static int SHELL_STYLE = PopupDialog.INFOPOPUP_SHELLSTYLE;
public MouseLocationPopupDialog(Shell parent, String infoText) {
this(parent, SHELL_STYLE, true, false, false, false, false, null, infoText);
}
public MouseLocationPopupDialog(Shell parent, String titleText, String infoText) {
this(parent, SHELL_STYLE, true, false, false, false, false, titleText, infoText);
}
public MouseLocationPopupDialog(Shell parent, String infoText, final Point size) {
this(parent, infoText);
getShell().setSize(size);
}
public MouseLocationPopupDialog(Shell parent, int shellStyle, boolean takeFocusOnOpen, boolean persistSize, boolean persistLocation, boolean showDialogMenu, boolean showPersistActions, String titleText, String infoText) {
super(parent, shellStyle, takeFocusOnOpen, persistSize, persistLocation, showDialogMenu, showPersistActions, titleText, infoText);
}
#Override
protected void adjustBounds() {
super.adjustBounds();
Display d = Display.getCurrent();
if (d == null) {
d = Display.getDefault();
}
Point point = d.getCursorLocation();
getShell().setLocation(point.x + 9, point.y + 14);
}
}
The actual usage is as follows:
final PopupDialog dialog = new MouseLocationPopupDialog(HandlerUtil.getActiveShell(event), "Title", "Bottom bar") {
#Override
protected Control createDialogArea(Composite parent) {
Control composite = super.createDialogArea(parent);
Composite table = new Composite((Composite) composite, SWT.NONE);
table.setLayout(new GridLayout(2, true));
// text is a member variable
text = new Text(table, SWT.SINGLE | SWT.BORDER);
Button submit = new Button(table, SWT.PUSH);
return composite;
}
#Override
protected Control createContents(Composite parent) {
Control contents = super.createContents(parent);
final Color backgroundColor = new Color(Display.getCurrent(), new RGB(255, 255, 255));
text.setBackground(backgroundColor);
final Color foregroundColor = new Color(Display.getCurrent(), new RGB(0,0,0));
text.setForeground(foregroundColor);
backgroundColor.dispose();
foregroundColor.dispose();
return contents;
}
};
dialog.open();
Note that this Popup is independent from other UI elements: The code will not wait for the completion of the popups open() like other JFace dialogs (e.g. TitleAreaDialog)
First of all, use SWT.BORDER instead of SWT.BORDER_SOLID. If you're lucky, this somehow causes your problem. Other than that, from your small snippet alone it's hard to see what goes wrong. Unless there is some other code that resets the background color later on, this should work.
Update:
Try to override the method getBackground() of PopupDialog and let it return the color you want. Your code probably is in createDialogArea(..) and PopupDialog applies this color to basically everything after your code.
If you only want to change the background color of specific controls, you could try the following:
#Override
protected Control createContents(Composite parent) {
Composite contents = super.createContents(parent);
// set the color here
return contents;
}
Related
I am creating a legend view and inside the shell is supposed to have a rectangle followed by a label describing the color. I was able to get the view to work using just a normal composite but the legend continues beyond the screen and no way of see it without making the window larger. I am trying to use a scrolledComposite view for my shell but when I execute the program, nothing appears.
public void createPartControl(Composite parent)
{
display = parent.getDisplay();
parent.setLayout(new FillLayout());
sc = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
LegendView.composite = new Composite(sc, SWT.NONE);
RowLayout layout = new RowLayout();
layout.wrap = true;
layout.spacing = 5;
composite.setLayout(layout);
}
public static void addRectangle(String legendMessage)
{
final String propId = legendMessage;
final String[] s = propId.split(",");
if (display != null)
{
display.syncExec(new Runnable()
{
#Override
public void run()
{
// Creating the color using the RBG values
final Color color =
new Color(display, Integer.parseInt(s[0]), Integer.parseInt(s[1]), Integer.parseInt(s[2]));
// Creating a canvas for which the rectangle can be drawn on
Canvas canvas = new Canvas(composite, SWT.NONE);
// Maybe set the bounds of the canvas
canvas.addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent e)
{
e.gc.drawRectangle(1, 1, 50, 60);
e.gc.setBackground(color);
e.gc.fillRectangle(2, 2, 49, 59);
}
});
// Disposing the color after it has been used
canvas.addDisposeListener(new DisposeListener()
{
public void widgetDisposed(DisposeEvent e)
{
color.dispose();
}
});
// Creating a label and setting the font
Label label = new Label(composite, SWT.NULL);
Font boldFont = new Font( label.getDisplay(), new FontData( "Arial", 12, SWT.BOLD ) );
label.setFont( boldFont );
label.setText(s[3]);
composite.redraw();
composite.layout(true);
sc.setContent(composite);
}
});
}
}
I am calling add rectangle in a different class. I am fairly new at using SWT and after looking at examples and reading the docs for scrolled Composite, this is what I interpreted it as. Any help would be very appreciated.
You haven't told the ScrolledComposite how to manage the size. You must either call setSize or setMinSize. For this you probably want:
sc.setExpandHorizontal(true);
sc.setExpandVertical(true);
sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
I have two comboviewer and the idea is that the second combo will display a subset of options depending of the first combo value selected. But after to set the new input in the second combo and refresh the combo width is too small. How can I set it for auto adjusting to options width?
public class ExpresionDialog extends Dialog {
private ComboViewer combo1;
private ComboViewer combo2;
#Override
protected Control createDialogArea(Composite composite) {
Composite parent = (Composite) super.createDialogArea(composite);
GridData data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
combo1 = new ComboViewer(parent);
combo1.setLabelProvider(new LabelProvider());
combo1.setContentProvider(ArrayContentProvider.getInstance());
combo1.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent e) {
IStructuredSelection sel = (IStructuredSelection) e.getSelection();
AttributeOption option = (AttributeOption) sel.getFirstElement();
combo2.setInput(getValuesCombo2(option));
combo2.refresh(true);
}
});
combo1.setInput(getValuesCombo1());
combo2 = new ComboViewer(parent);
combo2.setLabelProvider(new LabelProvider());
combo2.setContentProvider(ArrayContentProvider.getInstance());
return parent;
}
// Omitted getValuesCombo1 and getValuesCombo2 methods ...
}
You need to call the layout method of the parent Composite to get it to redo the child layouts each time you change the contents.
I have an Image in a grid that scales when the PartView is resized. If the BarsView starts smaller than 64 high (the size of the canvas), the bottom portion of the image gets cut off below the initial size. If it starts larger than what it is resized to, the minivitals does not shrink as it should. How can I the layout, when resized, to look like it does when I open the program at that size?
Screenshot of when the program is opened at normal size:
Shrunk after opening at normal size (notice the concentration bar is pushed off the bottom of the screen):
Opened at smaller size:
Opened at smaller size then expanded:
Restarting between resizing has the desired effect, except for the needing to restart part.
public class BarsView extends ViewPart {
private PageBook book;
public void createPartControl(Composite parent) {
book = new PageBook(parent, SWT.NONE);
book.setLayout(new FillLayout());
Composite page = new BarsPageView(book, view);
book.showPage(page);
}
private class BarsPageView extends Composite {
public BarsPageView(Composite parent, GameView view) {
super(parent, SWT.NONE);
this.setLayout(new GridLayout(3, false));
// This is a wrapper around a StyledText
entry = new StormFrontEntry(this, view);
GridData entryData = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
entryData.heightHint = 22;
entry.getWidget().setLayoutData(entryData); // getWidget() returns the StyledText
// This is a Composite containing a Canvas
status = new StormFrontStatus(this, view);
status.setLayoutData(new GridData(SWT.CENTER, SWT.BEGINNING, false, false));
// This is defined below
GridData compassData = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 2);
compassData.heightHint = 64;
compass = new WarlockCompass(this, SWT.NONE, theme, compassData);
compass.setLayoutData(compassData);
minivitals = new StormFrontDialogControl(this, SWT.NONE);
GridData mvData = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
minivitals.setLayoutData(mvData);
}
}
public class WarlockCompass extends Canvas {
public WarlockCompass (final Composite parent, int style, CompassTheme theme, GridData layoutData) {
super(parent, style);
addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
drawCompass(e.gc);
}
});
parent.addListener(SWT.Resize, new Listener() {
#Override
public void handleEvent(Event event) {
// I cut out the calculations for this
layoutData.heightHint = height;
WarlockCompass.this.setSize(width, height);
}
});
}
private void drawCompass (GC gc) {
// Cut out the calculations to scale the image to fix the canvas
gc.drawImage(scaledImage, 0, 0);
}
}
// This is defined below
GridData compassData = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 2);
compassData.heightHint = 64;
compass = new WarlockCompass(this, SWT.NONE, theme, compassData);
compass.setLayoutData(compassData);
Should have been:
// This is defined below
GridData compassData = new GridData(SWT.CENTER, SWT.CENTER, false, true, 1, 2);
compassData.heightHint = 64;
compass = new WarlockCompass(this, SWT.NONE, theme, compassData);
compass.setLayoutData(compassData);
Changing that flag makes it resize properly.
I've been banging away at this for a while now and I can't seem to get anywhere. I've tried all of the examples I can find online and nothing seems to work! I haven't been able to find much on this problem which leads me to think I'm missing something basic. . .
In my Eclipse RCP program I want to display a dialog that will show a list of errors that occurred while loading a data file. I have overridden TitleAreaDialog and simply want to display a scrollable Text containing the list of errors and an OK button.
The problem is that the Text vertical scroll bars don't become active - the Text just grows taller to fit the text. This makes the dialog window height increases until it either fits the Text box or until it reaches the height of the screen - and then it just cuts off the bottom of the Text box.
How do I prevent the Dialog/Text box from growing too large? What am I missing?
Thanks for your help!!
-Christine
...
Here is a simple program showing my Dialog:
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.*;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class ScrollableDialogRunner {
public static void main(String[] args) {
System.out.println("starting");
Display display = new Display ();
Shell shell = new Shell (display);
String errors = "one\ntwo\nthree\nfour\nfive\n";
for(int i = 0; i < 5; i++){
errors += errors;
}
ScrollableDialog dialog = new ScrollableDialog(shell, "Errors occurred during load", "The following errors occurred while loaded file 'x.data'", errors);
dialog.open();
}
}
class ScrollableDialog extends TitleAreaDialog {
private String title;
private String text;
private String scrollableText;
public ScrollableDialog(Shell parentShell, String title, String text, String scrollableText) {
super(parentShell);
this.title = title;
this.text = text;
this.scrollableText = scrollableText;
}
#Override
protected Control createDialogArea(Composite parent) {
GridLayout layout = new GridLayout();
layout.numColumns = 1;
parent.setLayout(layout);
GridData gridData = new GridData();
gridData.grabExcessHorizontalSpace = true;
gridData.horizontalAlignment = GridData.FILL;
Text scrollable = new Text(parent, SWT.BORDER | SWT.V_SCROLL);
scrollable.setLayoutData(gridData);
scrollable.setText(scrollableText);
return parent;
}
#Override
public void create() {
super.create();
setTitle(title);
setMessage(text, IMessageProvider.ERROR);
}
#Override
protected void createButtonsForButtonBar(Composite parent) {
Button okButton = createButton(parent, OK, "OK", true);
okButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
close();
}
});
}
#Override
protected boolean isResizable() {
return false;
}
}
Assign a size to the dialog; otherwise, the dialog will layout the children asking them for their "preferred" size (which is infinite for the text widget) and will resize itself accordingly.
[EDIT] This version works. See my comments for details.
class ScrollableDialog extends TitleAreaDialog {
private String title;
private String text;
private String scrollableText;
public ScrollableDialog(Shell parentShell, String title, String text, String scrollableText) {
super(parentShell);
this.title = title;
this.text = text;
this.scrollableText = scrollableText;
}
#Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea (parent); // Let the dialog create the parent composite
GridData gridData = new GridData();
gridData.grabExcessHorizontalSpace = true;
gridData.horizontalAlignment = GridData.FILL;
gridData.grabExcessVerticalSpace = true; // Layout vertically, too!
gridData.verticalAlignment = GridData.FILL;
Text scrollable = new Text(composite, SWT.BORDER | SWT.V_SCROLL);
scrollable.setLayoutData(gridData);
scrollable.setText(scrollableText);
return composite;
}
#Override
public void create() {
super.create();
// This is not necessary; the dialog will become bigger as the text grows but at the same time,
// the user will be able to see all (or at least more) of the error message at once
//getShell ().setSize (300, 300);
setTitle(title);
setMessage(text, IMessageProvider.ERROR);
}
#Override
protected void createButtonsForButtonBar(Composite parent) {
Button okButton = createButton(parent, OK, "OK", true);
okButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
close();
}
});
}
#Override
protected boolean isResizable() {
return true; // Allow the user to change the dialog size!
}
}
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();
}
}