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));
Related
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
I have implemented a custom view in my Eclipse plugin project, where I want to display different graphs, which are selected by the user. I have no problem with creating a custom view, using org.eclipse.swt.graphics.GC and drawing the required parts but I would like to implement the following:
Inside the custom view I want to have some fixed area on the bounds of the view, where I can display the coordinate system (x- and y-axis with the corresponding labeling), which is fixed. Between these bounds I would like to display the graph, which is changing dynamically, depending on user selection.
So what I need is a custom view, that is built like the following:
Inside the grey area on the left and on the bottom I want to have the coordinate system axes (shown red) and inside the white area I want to draw the graph.
How do I create such an area inside my view? It should just be a filed, without any translations or scales, just a independend area, like a view inside a view...
#Override
public void init(IViewSite site) throws PartInitException {
super.init(site);
}
#Override
public void createPartControl(Composite parent) {
canvas = new Canvas(parent, SWT.NONE);
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
drawCoordinateSystem(e);
drawGraph(e);
});
public void drawCoordinateSystem(PaintEvent e) {
// 1. create area inside view
// 2. draw coordinate system
}
public void drawGraph() {
// 3. draw graph
}
I know how to solve point 2 and 3. But I don't know, how to create such an area inside my view.
I would appreciate any help!
I would suggest that you add multiple controls and handle drawing for different cases in a different way.
For example, instead of having just one monolithic Canvas that draws everything from graph to coordinates, to helpful labels. Add a bunch of label controls on top for showing coordinates, add a parent, or labels for coordinate systems etc.
Your createPartControl should look something like below:
Composite topBar = new Composite(parent, SWT.None);
topBar.setLayout(new GridLayout(3, false));
Label title = new Label(topBar, SWT.NONE);
title.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
Label x = new Label(topBar, SWT.NONE);
Label y = new Label(topBar, SWT.NONE);
Composite graphArea = new Composite(parent, SWT.NONE);
graphArea.setLayout(new GridLayout(2, false));
Canvas xAxis = new Canvas(graphArea, SWT.NONE);
GridData gd = new GridData(GridData.CENTER, GridData.FILL, false, true);
gd.widthHint = 10;
xAxis.setLayoutData(gd);
xAxis.addPaintListener(new PaintListener() {
#Override
public void paintControl(PaintEvent e) {
drawXAxis();
}
});
Canvas graph = new Canvas(graphArea, SWT.NONE);
graph.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
drawGraph(e);
}
});
Label emptySpace = new Label(graphArea, SWT.NONE);
Canvas yAxis = new Canvas(graphArea, SWT.NONE);
GridData gd = new GridData(GridData.FILL, GridData.CENTER, true, false);
gd.heightHint = 10;
xAxis.setLayoutData(gd);
yAxis.addPaintListener(new PaintListener() {
#Override
public void paintControl(PaintEvent e) {
drawYAxis();
}
});
You should draw everything in Your paintListener, if Your graph changes just redraw area of graph for example:
Rectangle rect = getGraphBoundries(); //you must implement this method
canvas.redraw(rect.x, rect.y, rect.width, rect.height, true);
this will redraw graph area. To avoid unnecessary computing of axes area in in paintListener paintEvent's gc has area that need to be redrawn called clipping. You can write condition like this:
public void paintControl(PaintEvent e) {
...
if(drawGraph(e.gc.getClipping().intersects(getGraphBoundries())) {
drawGraph(e);
}
...
}
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'm attempting to create a window that is divided into three parts. A non-resizable header and footer and then a content area that expands to fill the remaining area in the window. To get started, I created the following class:
public class MyWindow extends ApplicationWindow {
Color white;
Font mainFont;
Font headerFont;
public MyWindow() {
super(null);
}
protected Control createContents(Composite parent) {
Display currentDisplay = Display.getCurrent();
white = new Color(currentDisplay, 255, 255, 255);
mainFont = new Font(currentDisplay, "Tahoma", 8, 0);
headerFont = new Font(currentDisplay, "Tahoma", 16, 0);
// Main layout Composites and overall FillLayout
Composite container = new Composite(parent, SWT.NO_RADIO_GROUP);
Composite header = new Composite(container, SWT.NO_RADIO_GROUP);
Composite mainContents = new Composite(container, SWT.NO_RADIO_GROUP);;
Composite footer = new Composite(container, SWT.NO_RADIO_GROUP);;
FillLayout containerLayout = new FillLayout(SWT.VERTICAL);
container.setLayout(containerLayout);
// Header
Label headerLabel = new Label(header, SWT.LEFT);
headerLabel.setText("Header");
headerLabel.setFont(headerFont);
// Main contents
Label contentsLabel = new Label(mainContents, SWT.CENTER);
contentsLabel.setText("Main Content Here");
contentsLabel.setFont(mainFont);
// Footer
Label footerLabel = new Label(footer, SWT.CENTER);
footerLabel.setText("Footer Here");
footerLabel.setFont(mainFont);
return container;
}
public void dispose() {
cleanUp();
}
#Override
protected void finalize() throws Throwable {
cleanUp();
super.finalize();
}
private void cleanUp() {
if (headerFont != null) {
headerFont.dispose();
}
if (mainFont != null) {
mainFont.dispose();
}
if (white != null) {
white.dispose();
}
}
}
And this results in an empty window when I run it like this:
public static void main(String[] args) {
MyWindow myWindow = new MyWindow();
myWindow.setBlockOnOpen(true);
myWindow.open();
Display.getCurrent().dispose();
}
What am I doing wrong that I don't see three labels the way I'm trying to display them? The createContents code is definitely being called, I can step through it in Eclipse in debug mode.
Apparently, I needed to set the size and location of the labels to get them to appear.
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();
}
}