Canvas too small to display Image in SWT - java

I'm trying to use a Canvas to display an animated gif. I have the animation working, but the canvas is too small to see the entire image, and I cannot get it to resize.
I can't even get it to be the right size for the first frame, so the animation/threading code is being omitted. My code looks like:
Composite comp = new Composite(parent, SWT.None);
comp.setLayout(new GridLayout(1, false));
final ImageLoader loader = new ImageLoader();
loader.load(getClass().getClassLoader().getResourceAsStream("MYFILE.gif"));
final Canvas canvas = new Canvas(comp, SWT.None);
final Image image = new Image(Display.getCurrent(), loader.data[0]);
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
e.gc.drawImage(image, 0, 0);
}
});
The canvas area ends up being a tiny box of around 30x30, regardless of how big MYFILE.gif is. What the hell?
Anything I try to use to set the canvas size (setSize, setBounds, etc) does nothing.

Try using setPreferredSize. The layout manager will call setSize and/or setBounds and clobber the values you have set, but it will try to respect preferred size if it can. You can also use setMaximumSize and setMinimumSize to control how the canvas will resize if the enclosing component is resized.
EDIT: For SWT you could try this:
GridData gridData = new GridData();
gridData.widthHint = imageWidth;
gridData.heightHint = imageHeight;
canvas.setLayoutData(gridData);
I'm not an SWT expert, but the SWT documentation seems helpful.

Related

Setting a JFreeChart ChartComposite to a fixed size in SWT

I'm trying to add JFree step charts to a scrollable view in eclipse as a plugin, but the charts keep resizing (kinda randomly) each time I modify the view's dimensions.
I want to set them to a fixed size, however large or small the view might get (that's why I made it scrollable in the first place) so I tried something like this:
public void createPartControl(final Composite parent) {
ScrolledComposite scrolled = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
Composite comp = new Composite(scrolled, SWT.NONE);
comp.setLayout(new FillLayout(SWT.VERTICAL));
final JFreeChart chart = createChart();
ChartComposite chartComposite1 = new ChartComposite(comp, SWT.NONE, chart, true);
// set chart size attempt
chartComposite1.setSize(500, 200);
chartComposite1.redraw();
comp.redraw();
scrolled.redraw();
// ScrolledComposite stuff
scrolled.setContent(comp);
scrolled.setExpandVertical(true);
scrolled.setExpandHorizontal(true);
scrolled.setAlwaysShowScrollBars(true);
scrolled.addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent e) {
org.eclipse.swt.graphics.Rectangle r = scrolled.getClientArea();
scrolled.setMinSize(parent.computeSize(r.width, SWT.DEFAULT));
}
});
But it doesn't do anything. The chart keeps auto resizing as I modify the view's size.
Any help?
Make sure that you undestand how layouts work in SWT. Understanding Layouts in SWT is a good start.
chartComposite1.setSize() is useless, it will be overwritten by the layout that was set in comp.setLayout( ... ).
... and forcing controls to redraw() doesn't help either as it doesn't update the location or size of controls.
As I suggested earlier, if you know the size of the charts, use a single columned GridLayout and control the size of the charts through GridData::widthHint and heightHint.

Simple way of scrolling over a certain rectangle with a JScrollPane and a JPanel (custom)

I have created a custom JPanel class called ImagePanel. I override the paintComponent method like this...
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0,0, null);
}
The purpose of the custom panel is to simply draw an image.
In my JFrame, I create a ScollPane that is added to the JFrame. When I created the ScrollPane though, I pass in the instance of my imagePanel, like this...
ip = new ImagePanel();
JScrollPane jsp = new JScrollPane(ip);
this.add(jsp);
Now all I want as an easy to use way of using the scroll bars to scroll over my image. Right now the image is very large and scrollbars do not appear. I use the policy to make them visible, but the handles to the scrollbars are not there.
Does anyone know an easy way to do this?
Try with JPanel#setPreferredSize() that will force the JScrollPane to show the scroll bar if needed.
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0,0, null);
// set the size of the panel based on image size
setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
}
EDIT
Setting setPreferredSize() inside overridden paintComponent() is not a good way.
You can do it in a simpler way using JLabel as suggested by #mKorbel. For more info have a look at the comments below.
BufferedImage image = ...
JLabel label = new JLabel(new ImageIcon(image)); // set the icon
JScrollPane jsp = new JScrollPane(label);
Screenshot:

TitleAreaDialog - adjusting the title image

So I am creating a image to place in the title area. Everything works with the exception that only a 1/4th of the image is displayed?
my image is actually text and a image combine in one image EX: JKTeater [ ] <-- icon
so right now only JKT is showing in the title area
Here is the create() method
public void create() {
super.create();
setTitle("JKTeater Application");
setMessage("Hello World");
if (image != null) setTitleImage(image);
}
Is there a specific size that the title area code allows for?
Is there a way to place the end of the image at the end of the title area?
Can you use a layout to move it around?
How can I get a black horizonal line at the bottom of the title area?
EDIT
I am sure that it would be asking to much to see if you can actually change the background color from a basic color to a gradient
Here is an example TitleAreaDialog. As you can see, the Image is completely shown and aligned to the right:
public static void main(String[] args) {
final Shell shell = new Shell();
shell.setLayout(new FillLayout());
TitleAreaDialog dialog = new MyTitleAreaDialog(shell);
dialog.setTitleAreaColor(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND).getRGB());
dialog.open();
}
private static class MyTitleAreaDialog extends TitleAreaDialog
{
private Image image;
public MyTitleAreaDialog(Shell parentShell) {
super(parentShell);
image = new Image(Display.getDefault(), "/home/baz/Desktop/StackOverflow.png");
}
#Override
public boolean close() {
if (image != null)
image.dispose();
return super.close();
}
#Override
protected Control createContents(Composite parent) {
Control contents = super.createContents(parent);
setTitle("Title");
setMessage("Message");
if (image != null)
setTitleImage(image);
return contents;
}
#Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
// YOUR LINE HERE!
Label line = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
line.setLayoutData(new GridData(SWT.FILL, SWT.END, true, true));
return composite;
}
}
Is there a specific size that the title area code allows for?
AFAIK there are no restrictions to the size. I tried using an Image that was larger than my screen resolution and it was fully displayed. The Dialog was obviously unusable though.
I am sure that it would be asking to much to see if you can actually change the background color from a basic color to a gradient
The background color can be changed using dialog.setTitleAreaColor(RGB) (in this case the widget background color), but you cannot use a gradient. There is a deprecated method getTitleArea() which would return the title area Composite, but I really wouldn't recommend using that.
How can I get a black horizonal line at the bottom of the title area?
The line at the bottom was achieved by using:
Label line = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
line.setLayoutData(new GridData(SWT.FILL, SWT.END, true, true));
Can you use a layout to move it around?
There is a similar question here:
Moving an image of a TitleAreaDialog to the left
The answers there explain how to change details of the TitleAreaDialog. Maybe read up on them.

Java swt canvas how does the paint listener work?

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.

JScrollPane not repaint Canvas when scrolling?

I trying to make a game where I add a Canvas to a JScrollPane but the canvas is larger than the visible area of the JScrollPane. So when I scroll the JScrollPane to see the rest I only see the blank area even though my Canvas is continuously redrawn. Anybody can help me??
It is common JScrollPane problem. To fix this with minimum fuss, call the following methods on your JScrollPane:
scrollpane.getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
Swing components do not work with heavyweight AWT components like Canvas. Use a JComponent or a JPanel instead of a Canvas
You need to use a lightweight JPanel and 2 heavyweight objects like:
JPanel foreground = new JPanel();
Panel frame = new Panel();
Cavas canvas = new Cavas();
foreground.add(frame);
frame.add(canvas);
Heavyweight objects might be AWT, or SWT (with OLE), or mixed, it does not matter.
Then get JScrollPane and add AdjustmentListener which calls method like:
private void updateLocation() {
final JScrollPane scroll = getScrollPane();
if (null == scroll) {
// do nothing
return;
}
final Point top = getLocation();
final Rectangle visible = getVisibleRect();
// set up new location
frame.setSize(visible.width, visible.height);
frame.setLocation(visible.x - top.x, visible.y - top.y);
canvas.setSize(getWidth(), getHeight());
canvas.setLocation(top.x - visible.x, top.y - visible.y);
}

Categories