I'm creating an editor extension to eclipse, and a for a part of the editor I need to draw simple graphical parts. From what I understand I should be able to use the eclipse widget Canvas for this. But the paintControl method of the PaintListener added to the canvas is never called. I'm assuming I'm missing some crucial simple part but I can't find it. Here is the code that creates, adds and calls redraw on the canvas.
void createGraphicPage() {
Composite composite = new Composite(getContainer(), SWT.NONE);
drawWidget = new Canvas(composite, SWT.NONE);
FormLayout layout = new FormLayout();
drawWidget.setLayout(layout);
drawWidget.addPaintListener(new PaintListener() {
#Override
public void paintControl(PaintEvent e) {
System.out.println("inDrawWidget");
Rectangle r = drawWidget.getClientArea();
e.gc.drawOval(0, 0, r.width, r.height);
}
});
drawWidget.redraw();
int index = addPage(composite);
setPageText(index, "Graphics Editor");
}
You need to set a layout on each Composite which contains controls, and usually set layout data on the controls. So:
Composite composite = new Composite(getContainer(), SWT.NONE);
composite.setLayout(new GridLayout());
Canvas drawWidget = new Canvas(composite, SWT.NONE);
drawWidget.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
drawWidget.addPaintListener(new PaintListener() {
#Override
public void paintControl(final PaintEvent e) {
System.out.println("inDrawWidget");
final Rectangle r = drawWidget.getClientArea();
e.gc.drawOval(0, 0, r.width, r.height);
}
});
I have added a GridLayout to the Composite and GridData layout data to the Canvas. The GridData makes the Canvas use all available space.
Related
I have a composite, which has 3 UI controls - SWT Group, SWT TabFolder, and a child composite that has a label and a link. In some use-cases the SWT Group is hidden, and I would like that the blank space is not seen instead the composite has to be redrawn and show only the SWT TabFolder and the child composite, without any space.
I'm using composite.layout(true), but still there is blank space of the SWT Group when it is made hidden.
Could someone help me solve this issue
TestComposite extends Composite{
private Label childlabel;
private Group group;
private TabFolder tabFolder;
private Button button;
TestComposite(Compossite parent){
super(parent, SWT.NONE);
setLayout(new GridLayout(1, true));
setFont(parent.getFont());
setBackground(parent.getBackground());
GridDataFactory.fillDefaults().grab(true, true).applyTo(this);
createControl();
}
public void createControl() {
this.group = new Group(this, SWT.SHADOW_IN);
this.group.setSize(this.getDisplay().getActiveShell().getSize());
this.button = new Button(this.group, SWT.PUSH);
GridDataFactory.swtDefaults().applyTo(this.button);
this.tabFolder = new TabFolder(this, SWT.TOP);
GridDataFactory.swtDefaults().align(SWT.FILL, SWT.FILL).grab(true,
true).applyTo(this.tabFolder);
Composite childComposite = new Composite(this, SWT.NONE);
childComposite .setLayout(new GridLayout(2, false));
GridDataFactory.swtDefaults().grab(true, false).align(SWT.LEFT,
SWT.TOP).applyTo(childComposite );
this.childLabel = new Label(childComposite, SWT.NONE);
GridDataFactory.swtDefaults().grab(true, false).applyTo(childlabel);
setInput(abc);
enableVisibilityOfGroup(false);
}
public void enableVisibilityOfGroup(Boolean visible){
this.group.setVisible(visible);
// this shoudl redraw the UI and shown only tabFolder and label in the
// whole wizard page, but there is blank space in place of group
this.layout(true);
}
}
Set GridData on the Group
GridDataFactory.swtDefaults().applyTo(this.group);
Use GridData.exclude to exclude/include the group in the layout:
public void enableVisibilityOfGroup(boolean visible) {
this.group.setVisible(visible);
GridData gridData = (GridData)this.group.getLayoutData();
gridData.exclude = !visible;
this.layout(true);
}
In my Eclipse plugin editor there is a button called "Add Graph" which adds a composite with a graph on another already created composite with "Grid Layout", but the created composite is not appearing until resizing the Editor manually or switch to another editor and go back
i have also used
parentComposite.pack();
parentComposite.layout();
but the added composite is shown up with a small size, and it`s adjusted also after resizing the Editor manually or switch to another editor and go back.
So my Question is how to call the same handler which runs while resizing the Editor manually or switch to another editor and go back. to adjust my view after adding the new composite.
Adding the Example:
public class MyEditor extends EditorPart {
private Composite compGraphesArea;
#Override
public void createPartControl(Composite parent) {
Composite container = new Composite(parent, SWT.NONE);
container.setLayout(new GridLayout(2, false));
Button btnAddGraph = new Button(container, SWT.NONE);
btnAddGraph.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
createGraph(compGraphesArea);
}
});
btnAddGraph.setText("Add Graph");
compGraphesArea = new Composite(container, SWT.NONE);
compGraphesArea.setLayout(new GridLayout(1, true));
compGraphesArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
createGraph(compGraphesArea);
}
private void createGraph(Composite compGraphArea) {
JFreeChart chart = chartHandler.getChart();
compGraphPlot = new Composite(compGraphArea, SWT.BORDER | SWT.EMBEDDED);
compGraphPlot.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
Frame chartFrame = SWT_AWT.new_Frame(compGraphPlot);
ChartPanel label = new ChartPanel(chart);
chartFrame.add(label);
chartFrame.pack();
chartFrame.setVisible(true);
XYPlot plot = chart.getXYPlot();
ValueAxis axis = plot.getDomainAxis();
axis.setFixedAutoRange(1000000 + slider.getMaximum() / 2);
}
And this what i got after pressing "Add Graph":
and this what i am expecting and what i got after making any change on the Editor manually:
I'm trying to put a ScrolledComposite on my UI with SWT.
but now it only shows blank area or something wrong.
The area to show ScrolledComposite is blank without the code,
"optionCompositeAtLeft.setSize(optionCompositeAtLeft.computeSize(SWT.DEFAULT, SWT.DEFAULT)); "
This is the pic of screenshot.
The optionTab should have the buttons with Scroll....
and with the code, it shows scroll, but too long height and narrow width.
Somehow, the upper is gone, but come back when I extend the size of window with scroll disappearing.
I set the color of background red to make it easier to see for you.
Can anyone help me make "optionCompositeAtLeft" filled in ScrolledComposite?
I want the left area of Option tab to be filled with a red background from "optionCompositeAtLef".
Below is my code.
private BomCloneDialog dialog = null;
private TabFolder tabFolder = null;
private TabItem tabOption = null;
public CreateOptionTab(TabFolder tabFolder, TabItem tabOption) {
this.tabFolder = tabFolder;
this.tabOption = tabOption;
}
public void createOptionTabUI() {
GridData gdWithFillBoth = new GridData(GridData.FILL_BOTH);
Composite optionComposite = new Composite(tabFolder, SWT.NONE);
optionComposite.setLayout(new GridLayout(2, true));
tabOption.setControl(optionComposite);
ScrolledComposite scrolledCompositeForOption = new ScrolledComposite(optionComposite,SWT.V_SCROLL | SWT.BORDER);
scrolledCompositeForOption.setLayoutData(gdWithFillBoth);
Composite optionCompositeAtLeft = new Composite(scrolledCompositeForOption, SWT.BORDER);
scrolledCompositeForOption.setContent(optionCompositeAtLeft);
optionCompositeAtLeft.setLayout(new GridLayout(1, true));
optionCompositeAtLeft.setLayoutData(gdWithFillBoth);
optionCompositeAtLeft.setBackground(new Color(Display.getCurrent(), 255,0,0));
Button b [] = new Button[30];
for(int a=0; a<30; a++){
b[a] = new Button(optionCompositeAtLeft, SWT.PUSH);
b[a].setText("button"+a);
}
**optionCompositeAtLeft.setSize(optionCompositeAtLeft.computeSize(SWT.DEFAULT, SWT.DEFAULT));**
Composite optionButtonComposite = new Composite(optionComposite, SWT.BORDER);
optionButtonComposite.setLayout(new GridLayout(1, true));
optionButtonComposite.setLayoutData(gdWithFillBoth);
Button optionSaveButton = new Button(optionButtonComposite, SWT.NONE);
optionSaveButton.setLayoutData(gdWithFillBoth);
optionSaveButton.setText("Save");
Button optionAddButton = new Button(optionButtonComposite, SWT.NONE);
optionAddButton.setLayoutData(gdWithFillBoth);
optionAddButton.setText("Add");
}
You need to configure ScrolledComposite to resize the content:
scrolledCompositeForOption.setExpandHorizontal(true);
scrolledCompositeForOption.setExpandVertical(true);
I want to add some objects into an Composite object. Objects can have different shapes (rectangle, circle, ellipse or even weird shape (represented by a polygon). So I defined classes like this:
public class Circle extends Canvas {
}
public class Rectangle extends Canvas {
}
...
I know how to draw in a Canvas to get the shape I want, but I also expected that the popup menu appears at each canvas only if the users click mouse inside the canvas area, so if I use these code in a composite class:
Menu aSampleMenu = new Menu(this);
Circle circle = new Circle(parent, style);
circle.setMenu(aSampleMenu);
the menu will appear if the user click right mouse button anywhere inside the canvas, even outside the shape area. How can I fix this problem?
Have a look at the code snippet below. The trick is defining the Menu first and then setting it only to those Controls that should allow menu detection:
public class StackOverflow
{
public static void main(String[] args)
{
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout(2, true));
Composite c1 = new Composite(shell, SWT.BORDER);
c1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Composite c2 = new Composite(shell, SWT.BORDER);
c2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Menu menu = new Menu(shell, SWT.POP_UP);
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText("Popup");
new Label(shell, SWT.BORDER).setText("No menu here");
new Label(shell, SWT.BORDER).setText("No menu here");
// Add menu only to c1 and c2, not to the shell and not to the labels
c1.setMenu(menu);
c2.setMenu(menu);
shell.setSize(300, 300);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
Here is a screenshot:
One solution is using Region, but I still dont figure out how it can be applied to circle case:
Region region = new Region();
region.add(new int[] {3, 3, 20, 20, 3, 20});
Canvas c = new Canvas(this, SWT.NONE);
c.setBounds(35, 35, 60, 60);
c.setRegion(region);
Menu menu = new Menu(this);
c.setMenu(menu);
MenuItem mntmProperties = new MenuItem(menu, SWT.NONE);
mntmProperties.setText("Properties");
MenuItem mntmDelete = new MenuItem(menu, SWT.NONE);
mntmDelete.setText("Delete");
I've just started working with swt's canvas. I'm under the impression that draw commands from the graphics controller (gc) can be executed in any listener that is attached to the canvas. I guess though, my question is what triggers the paint listener method paintControl?
Does the canvas.redraw() cause this to run as well?
Thanks for anyone who can point me in the right direction. If there are tutorials or books I can read on the matter(2d drawing in swt in general as well), I would love to hear of them.
EDIT:
Here is the code, I'm running into an issue where the graphCanvas is not filling excess vertical space? It doesn't work when I have it fill excessHorizontal space either. But it seems to work when I apply those properties to the composites. Any idea?
Color black = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
chartComposite = new Composite(parent, SWT.NONE);
GridLayout chartGridLayout = new GridLayout(1,false);
GridData chartGridData = new GridData();
chartGridData.grabExcessHorizontalSpace = true;
chartGridData.grabExcessVerticalSpace = true;
chartComposite.setLayout(chartGridLayout);
chartComposite.setLayoutData(chartGridData);
chartInnerComposite = new Composite(chartComposite, SWT.NONE);
GridLayout chartInnerGridLayout = new GridLayout(2,false);
GridData chartInnerGridData = new GridData();
chartInnerGridData.grabExcessHorizontalSpace = true;
chartInnerGridData.grabExcessVerticalSpace = true;
chartInnerComposite.setLayout(chartInnerGridLayout);
chartInnerComposite.setLayoutData(chartInnerGridData);
/**
* Create the four canvases
*/
Canvas yCanvas = new Canvas(chartInnerComposite, SWT.None);
graphCanvas = new Canvas(chartInnerComposite, SWT.None);
GridLayout graphGridLayout = new GridLayout(1, false);
graphGridLayout.makeColumnsEqualWidth = false;
GridData graphGridData = new GridData(SWT.FILL);
graphGridData.widthHint = 400;
graphGridData.grabExcessVerticalSpace = true;
graphCanvas.setLayout(graphGridLayout);
graphCanvas.setLayoutData(graphGridData);
graphCanvas.addPaintListener(new PaintListener() {
#Override
public void paintControl(PaintEvent e) {
e.gc.drawLine(20, 20, 500, 500);
e.gc.drawRectangle(0, 0, graphCanvas.getSize().x -1, graphCanvas.getSize().y -1);
e.gc.drawLine(0, 40, 500, 500);
e.gc.drawLine(0, 0, 0, 1200);
e.gc.drawLine(0, 0, 1200, 0);
}
});
/*graphCanvas.setSize(400, 400);
graphCanvas.redraw();
graphCanvas.update();*/
Canvas filler = new Canvas(chartInnerComposite, SWT.NONE);
Canvas xCanvas = new Canvas(chartInnerComposite, SWT.None);
Your code can definitely call canvas.redraw() manually, which will then trigger a paintControl event. SWT itself will also cause repaints to be triggered as needed, for things like window resizing and when the canvas gets obscured/un-obscured by other windows.