Images getting cut off using Swing - eclipse

I am writing a tile based platform game. At the moment I am trying to get 400 tiles to display at once. This is my panel. On the top and left sides everything is working great but on the right and bottom sides the images are cut off by a few pixels. Each image is 32*32. All of blocks are initialized. None are null. What is wrong here?
public class Pane extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
Timer timer;
boolean setup = false;
Block[][] blocks;
Level level;
public Pane()
{
level = new Level();
level.Generate();
blocks = level.Parse();
setBackground(Color.WHITE);
timer = new Timer(25, this);
timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
for(Block[] b : blocks)
{
for(Block bx : b)
{
// Debug code if(bx.letter.equals("D"))
// Debug codeSystem.out.println(bx.y*32 +" = "+ bx.x*32);
g2d.drawImage(bx.bpic, bx.x*32, bx.y*32, this);
}
}
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}

on the right and bottom sides the images are cut off by a few pixels
If you mean the right and bottom sides of the whole panel (not on the single tiles), than it's probably a LayoutManager related problem. The solution depends on the layout manager you are using for the component your JPanel will be added to.
You could try to specify the minimum/preferred size of your JPanel with:
Pane pane = new Pane();
pane.setPreferredSize(...);
pane.setMinimumSize(...);
In order to specify its minimum dimension accordingly to the size of the generated image (32 * COL , 32 * ROW).
Unfortunately the effectiveness of the setPreferredSize call depends on the layout manager of your Pane parent component.

JComponent can do that basically and can return very easily something as MinimumSize or PreferredSize, valid for majority of standard Swing LayoutManagers, examples here.

Related

Why is draw_picture called so many times?

When I run the following programme:
//compile: valac --pkg gtk+-3.0 sample.vala
using Gtk;
public class Main : Object
{
private Window window;
private Gdk.Pixbuf pixbuf;
private DrawingArea da1;
public Main()
{
window = new Window();
window.destroy.connect (main_quit);
pixbuf = new Gdk.Pixbuf.from_file("sample.jpg");
var box = new Box (Orientation.VERTICAL, 5);
da1 = new DrawingArea();
da1.set_hexpand(true);
da1.set_vexpand(true);
da1.draw.connect((context) => draw_picture(context, pixbuf));
box.pack_start (da1, true, true, 0);
window.add (box);
window.show_all();
}
bool draw_picture(Cairo.Context cr, Gdk.Pixbuf pixbuf)
{
print("draw_picture\n");
int width = da1.get_allocated_width();
int height = da1.get_allocated_height();
var temp = pixbuf.scale_simple(width, height, Gdk.InterpType.BILINEAR);
Gdk.cairo_set_source_pixbuf (cr, temp, 0, 0);
cr.paint ();
return false;
}
static int main(string[] args)
{
Gtk.init(ref args);
var app = new Main();
Gtk.main();
return 0;
}
}
after start I can see 'draw_picture' printed 2 times. When I switch window to terminal, it's displayed additional 7 times. Can anyone explain why and recommend some good book explaining the details?
In order to answer that question for sure, you would need to look at how your window manager works. Probably the redraws that occur when you switch to another window are due to the widget gaining the :backdrop pseudoclass when its window ceases to be the active window.
In general a widget's draw signal is invoked whenever the window manager needs to redraw a portion of the window that includes the widget, and also whenever the widget's active style changes.
If your widget is expensive to redraw then you can avoid drawing the whole thing when it's not necessary. The Cairo context's clip region will be set to the portion which needs redrawing.

Fake scrolling with JavaFX 8 ScrollPane

What I'm trying to do:
I'm trying to render a game board for a user using a canvas. The user
will be able to zoom.
Rendering the entire game board is impossible when the user is
zoomed in as the game board is very large. Instead I will render what
is onscreen every 1/30 sec.
I would like to create the illusion of the entire game board beings
inside a gui like the ScrollPane where the user can scroll with a
mouse.
In reality the ScrollPane will be linked to a single canvas exactly
the size of the viewport.
I'm not sure what the right way to go about this is. The scroll pane does not seem to have a property that allows you to pretend it has a large object in it. I could place a large canvas in the scroll pane but large canvases take up memory, as my crashes have suggested. Should I be using an AnchorPane or something? What's the proper way to do this?
It seems like putting an AnchorPane into the ScrollPane, setting that AnchorPane to the correct size (the size of the entire gameboard) works well to let the user scroll freely. From there all you have to do is put a canvas in the AnchorPane at the right place and keep moving it (and redrawing it) makes everything work out. To make it run smoothly I think you should render 100 to 500 pixels outside of the viewport of the ScrollPane. Here's some example code from my project:
public class GridViewPane {
/** ScrollPane that this grid exits in */
private ScrollPane gridScroll;
/** The anchor pane immediately inside of {#link #gridScroll}. The
* dimensions of this equals the dimensions of the {#link #can} if it was to
* render the entire grid at once */
private Pane gridView;
/** Exists in {#link #gridView} and is exactly the size of the viewport of
* {#link #gridScroll} */
private Canvas can;
/** A label the specifies what hex is currently moused-over */
private Label currentHexLabel;
public void update() {
// sets the canvas to the right size if needed
final Bounds viewportSize = gridScroll.getBoundsInLocal();
if (can == null || !can.getBoundsInLocal().equals(viewportSize)) {
can = new Canvas(viewportSize.getWidth(),
viewportSize.getHeight());
gc = can.getGraphicsContext2D();
}
// sets the anchorpane to the right size
final double[] dim = getPixleSizeOfGrid(w.columns(), w.rows(), r);
if (gridView == null) {
gridView = new AnchorPane();
gridScroll.setContent(gridView);
}
Bounds oldDim = gridView.getBoundsInLocal();
if (!(oldDim.getWidth() == dim[0]
&& oldDim.getHeight() == dim[1])) {
gridView.setPrefSize(dim[0], dim[1]);
}
// puts the canvas in the right position
if (!gridView.getChildren().contains(can))
gridView.getChildren().add(can);
double[] x = getXScreenRange();
double[] y = getYScreenRange();
can.relocate(x[0], y[0]);
// *********** Drawing Hexes ***********/
}
}

GWT Google Map Api V3 - broken when changing it

It is working fine for me for the first time it is rendered.
But, If I change anything over the map or recreate it, its broken.
Here is the screen shot for how it looks.
Here is a screen shot after I changed the results per page value.
This is my code.
#UiField DivElement mapPanel;
private GoogleMap googleMap;
public void loadAllMarkers(final List<LatLng> markers)
{
if(!markers.isEmpty())
{
final MapOptions options = MapOptions.create();
options.setMapTypeId(MapTypeId.ROADMAP);
googleMap = GoogleMap.create(mapPanel, options);
final LatLngBounds latLngBounds = LatLngBounds.create();
for(LatLng latLng : markers)
{
final MarkerOptions markerOptions = MarkerOptions.create();
markerOptions.setPosition(latLng);
markerOptions.setMap(googleMap);
final Marker marker = Marker.create(markerOptions);
latLngBounds.extend(marker.getPosition());
}
googleMap.setCenter(latLngBounds.getCenter());
googleMap.fitBounds(latLngBounds);
}
}
I am calling the loadAllMarkers() method whenever new results needs to be loaded.
Can someone point out what I am doing wrong here.
This seems to come from the following (which I pulled from a Google+ Community - GWT Maps V3 API):
Brandon DonnelsonMar 5, 2013
I've had this happen and forgotten why it is, but
mapwidget.triggerResize() will reset the tiles. This seems to happen
when the onAttach occurs and animation exists meaning that the div
started smaller and increases in side, but the map has already
attached. At the end of the animation, the map doesn't auto resize.
I'v been meaning to investigate auto resize but I haven't had time to
attack it yet.
In your case, you would call googleMap.triggerResize() after you finish your changes. this solved my problem when I had the exact same issue. I know it's a little late, but I hope it helps!
Another answer there was to extend the Map widget with the following:
#Override
protected void onAttach() {
super.onAttach();
Timer timer = new Timer() {
#Override
public void run() {
resize();
}
};
timer.schedule(5);
}
/*
* This method is called to fix the Map loading issue when opening
* multiple instances of maps in different tabs
* Triggers a resize event to be consumed by google api in order to resize view
* after attach.
*
*/
public void resize() {
LatLng center = this.getCenter();
MapHandlerRegistration.trigger(this, MapEventType.RESIZE);
this.setCenter(center);
}

get in the center of the composite? eclipse

My purpose is to draw in the CENTER of the composite. Actually, I have an rcp view and I'm drawing some shapes inside it. this is the code that I use :
display = parent.getDisplay();
white= display.getSystemColor(SWT.COLOR_WHITE);
parent.setLayout(new FillLayout(SWT.VERTICAL));
// Create the ScrolledComposite to scroll horizontally and vertically
final ScrolledComposite sc =new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
sc.setExpandHorizontal(true);
sc.setExpandVertical(true);
sc.setMinHeight(100);
sc.setMinWidth(100);
sc.setSize(100,100);
Composite child = new Composite(sc,SWT.NONE);
child.setLayout(new FillLayout());
child.layout(true);
parent.addListener (SWT.Resize, new Listener () {
public void handleEvent (Event e) {
x = child.getBounds().width/2;
y = child.getBounds().height/2;
child.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent event) {
dessin(gc); // to raw the circle
}
});
sc.getDisplay().update();
}
});
I defined the view with a ratio (so when the view is empty I get the wanted size)...I don't know the exact size of the view since it can be resized by the user at anymoment, or when an editor is opened... So, my problem is how to draw just in the center of the view and keep the drawings in the center even if the view is resized...
PS: Using (Point.x and point.y), I get (0,0) when the view appears first, then I get other values...
Pleaaaaaaaaaaaaaase help
You can use getOrigin() method on ScrolledComposite, which will return Point instance with the point in the content that currently appears in the top left corner of the scrolled composite. See docs getOrigin method on ScrolledComposite.
With that information and size of the component which you'll get from getBounds() method you can easily calculate the 'real' center.

How to create a GEF figure with separate label?

I've been trying to create a Draw2D Figure that consists of two parts - a central resizeable shape, such as a circle or rectangle, and an editable label for the bottom part. An example of this type of figure is the icon/label you see on a computer's Desktop.
The first attempt was to create a parent container figure with two child sub-figures - a shape figure placed centrally and a label placed at the bottom. It also implemented HandleBounds so that selection and resizing occurs only on the upper shape sub-figure. This turned out not to be a working solution because as the label gets wider with more text so does the main parent figure and consequently the central shape figure. In other words the overall parent figure is as wide as the child label figure.
What I'm seeking is a Figure that maintains the size of the shape figure but allows the width of the label figure to grow independently. Exactly the same behaviour as a desktop icon.
Ok I get your question right now. It's impossible to do what you want:
The parent figure can't be smaller than one of its children or this child will not be visible !!!
You have to create a container figure as you mentioned with an XYLayout and "manually" place and "size" the 2 (the shape and the label) children figure inside this layout using the IFigure.add(IFigure child, Object constraint) method with a Constraint of type Rectangle (Draw2d)
Edit with code sample
Here is an example of what your figure class could look like:
package draw2dtest.views;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Ellipse;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FigureListener;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Rectangle;
public class LabeledFigure extends Figure {
private final Figure shapeFigure;
private final Label labelFigure;
private Rectangle customShapeConstraint;
public LabeledFigure(String label) {
setLayoutManager(new XYLayout());
setBackgroundColor(ColorConstants.lightGray);
setOpaque(true);
shapeFigure = new Ellipse();
this.add(shapeFigure);
shapeFigure.setBackgroundColor(ColorConstants.yellow);
shapeFigure.addMouseListener(new MouseListener.Stub() {
#Override
public void mousePressed(MouseEvent me) {
customShapeConstraint = new Rectangle(
(Rectangle) LabeledFigure.this.getLayoutManager()
.getConstraint(shapeFigure));
customShapeConstraint.width -= 6;
customShapeConstraint.x += 3;
LabeledFigure.this.getLayoutManager().setConstraint(
shapeFigure, customShapeConstraint);
LabeledFigure.this.revalidate();
}
});
labelFigure = new Label(label);
labelFigure.setOpaque(true);
labelFigure.setBackgroundColor(ColorConstants.green);
labelFigure.addMouseListener(new MouseListener.Stub() {
#Override
public void mousePressed(MouseEvent me) {
Rectangle shapeFigureConstraint = new Rectangle(0, 0,
bounds.width, bounds.height - 15);
LabeledFigure.this.getLayoutManager().setConstraint(
shapeFigure, shapeFigureConstraint);
LabeledFigure.this.revalidate();
}
});
this.add(labelFigure);
this.addFigureListener(new FigureListener() {
#Override
public void figureMoved(IFigure source) {
Rectangle bounds = LabeledFigure.this.getBounds();
Rectangle shapeFigureConstraint = new Rectangle(0, 0,
bounds.width, bounds.height - 15);
LabeledFigure.this.getLayoutManager().setConstraint(
shapeFigure, shapeFigureConstraint);
Rectangle labelFigureConstraint = new Rectangle(0,
bounds.height - 15, bounds.width, 15);
if (customShapeConstraint != null) {
labelFigureConstraint = customShapeConstraint;
}
LabeledFigure.this.getLayoutManager().setConstraint(
labelFigure, labelFigureConstraint);
}
});
}
}
This is not a clean class but it should be a good entry to show you how to achieve your goal. This is an example based on pure Draw2d without any Gef code, thus the resizing of the shape is done by clicking in the yellow Ellipse (the size is decreased) and on the green label (the initial size is restored)
To test this class I created a simple Eclipse view as following:
#Override
public void createPartControl(Composite parent) {
FigureCanvas fc = new FigureCanvas(parent, SWT.DOUBLE_BUFFERED);
fc.setBackground(ColorConstants.red);
Panel panel = new Panel();
panel.setLayoutManager(new XYLayout());
LabeledFigure labeledFigure = new LabeledFigure("This is the label");
fc.setContents(panel);
panel.add(labeledFigure, new Rectangle(10,10, 200,100));
}
Hope this can help,
Manu