I am trying to center an ImageView in a JavaFX GUI. However, the image just appears in the top left corner of the window.
My code:
FlowPane picPane = new FlowPane();
Image photo = new Image(url, 300, 300, false, false);
ImageView myView = new ImageView(photo);
picPane.getChildren().add(myView);
picPane.setColumnHalignment(HPos.CENTER);
The property "columnHalignment" is ignored for horizontal flowpanes (default settings).
Take a look at the HBox Layout. There you can specify the alignment properly.
EDIT: some code:
public HBox addHBox(URL url) {
HBox hbox = new HBox();
hbox.setPadding(new Insets(15, 12, 15, 12));
hbox.setSpacing(10);
hbox.setStyle("-fx-background-color: #336699;");
hbox.setAlignment(Pos.TOP_CENTER);
Image photo = new Image(url, 300, 300, false, false);
ImageView myView = new ImageView(photo);
hbox.getChildren().add(myView);
return hbox;
}
I am very sorry. I cannot test it at the moment. But it should work this way.
This is the simplest solution I found.
Image img = new Image( "file:"+ imgURL );
imgViewer.setImage(img);
centerImage(imgViewer); // this does the centering..
public static void centerImage(ImageView imgView) {
Image img = imgView.getImage();
if (img != null) {
double w = 0;
double h = 0;
double ratioX = imgView.getFitWidth() / img.getWidth();
double ratioY = imgView.getFitHeight() / img.getHeight();
double reducCoeff = 0;
if(ratioX >= ratioY) {
reducCoeff = ratioY;
} else {
reducCoeff = ratioX;
}
w = img.getWidth() * reducCoeff;
h = img.getHeight() * reducCoeff;
imgView.setX((imgView.getFitWidth() - w) / 2);
imgView.setY((imgView.getFitHeight() - h) / 2);
}
}
Just modified from this link's solution a little: Centering an image in an ImageView
Your Image object sits in myview,
myview sits in picPain.
picPain is centered, however its' contents are not centered in terms of "drawing" with the image holder Graphics object!
The component drawing is myview.
Second, the size of the container myview requires measuring on each side from the container picPain.
While containers have alignments of their internal contents "they have defaults for their sizing and position they draw from the top left corner".
Set them and calculate them!
Related
I am trying to put squares to the application window. I am using gridpane and ı need to put 16 square with 4x4 array . With gridpane ı can create 3 row 4 column array , however ı can't put squares to the bottom row. Here is my code and results :
public void start(Stage primaryStage) throws Exception {
GridPane grid = new GridPane();
Scene scene = new Scene(grid, 400, 400);
Image image = new Image("Pipe_Vertical.jpg");
Image image2 = new Image("Empty.jpg");
ImageView imageView = new ImageView(image2);
imageView.setFitHeight(100);
imageView.setFitWidth(100);
ImageView imageView2 = new ImageView(image2);
imageView2.setFitHeight(100);
imageView2.setFitWidth(100);
ImageView imageView3 = new ImageView(image2);
imageView3.setFitHeight(100);
imageView3.setFitWidth(100);
ImageView imageView4 = new ImageView(image2);
imageView4.setFitHeight(100);
imageView4.setFitWidth(100);
ImageView imageView5 = new ImageView(image2);
imageView5.setFitHeight(100);
imageView5.setFitWidth(100);
ImageView imageView6 = new ImageView(image2);
imageView6.setFitHeight(100);
imageView6.setFitWidth(100);
grid.add(imageView3, 0, 0);
grid.add(imageView4, 1, 0);
grid.add(imageView2, 2, 0);
grid.add(imageView, 3, 0);
grid.add(imageView5, 0, 1);
grid.add(imageView6, 3, 3);
primaryStage.setTitle("Test");
primaryStage.setScene(scene);
primaryStage.show();
And this is what it looks when ı run it : Test Results :
grid.add(imageView6, 3, 3);
this part of the code should have put the square to the bottom right side but it is appearing on the wrong place.
Problem Solved. Needed to use
for (int i = 0; i < 4; i++) {
RowConstraints row = new RowConstraints(100);
grid.getRowConstraints().add(row);
}
It creates 4 rows with 100 pixel height.
I am trying to put the bitmap in the center of my layout (Center-horizontal) but my bitmap always starts with the left and not centered. I assign the x value to setbound which center my image but shrink it rather the maintaining the ratio I selected.
private void setImageinText(Bitmap myBitmap){
myBitmap = Util.scaleBitmapToFitWidth(myBitmap, 1360, true);
Drawable d = new BitmapDrawable(getResources(), myBitmap);
Point outSize = new Point();
WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
display.getSize(outSize);
int[] widthAndHeight = new int[2];
widthAndHeight[0] = outSize.x;
int x = (widthAndHeight[0]- d.getIntrinsicWidth())/2;
SpannableString ssd = new SpannableString("\n \n");
d.setBounds(x, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
ssd.setSpan(span, 1 , 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
texto.setTransformationMethod(null);
texto.getText().insert(texto.getSelectionStart(), ssd);
}
take ImageView below TextView and set it Centerhorizontal with Visibility GONE, then when you capture image set it in that ImageView and VISIBLE it.
I try to align the vertical scroll position of two javafx.scene.control.ScrollPanes via
sp1.vvalueProperty().bindBidirectional(sp2.vvalueProperty());
The problem is that one of these ScrollPanes may have a horizontal scroll bar. So the more I scroll down the ScrollPanes, the more they get misaligned (see screenshot). How can I handle this?
It's impossible to do this with 2 ScrollPanes and contents of equal height unless you display the scrollbar in both ScrollPanes:
Consider the case where the content fits the viewport of the left ScrollPane exactly. The viewPort of the right ScrollPane can be scrolled by the ScrollBar height. Modifying the left ScrollPane is not possible.
Since the expected result seems to be some kind of scale, you could simply use a Pane with a child you apply transformY to and a clip. The formula to calculate the pixel to be placed at the top, use
top = vvalue * (contentHeight - viewportHeight)
Example
private static Label createLabel(int num, boolean mark) {
Label label = new Label(Integer.toString(num));
label.setPrefSize(50, 50);
label.setMaxSize(Double.MAX_VALUE, Region.USE_PREF_SIZE);
label.setStyle(mark ? "-fx-background-color: #FFFFFF" : "-fx-background-color: #BBBBBB;");
return label;
}
#Override
public void start(Stage primaryStage) throws Exception {
VBox scale = new VBox();
scale.setMinHeight(Region.USE_PREF_SIZE);
GridPane content = new GridPane();
for (int i = 0; i < 40; i++) {
boolean b = ((i % 2) == 0);
scale.getChildren().add(createLabel(i, !b));
for (int j = 0; j < 10; j++) {
content.add(createLabel(i * 10 + j, b), j, i);
}
}
AnchorPane scaleContainer = new AnchorPane(scale);
scaleContainer.setMinWidth(30);
scaleContainer.setMinHeight(0);
AnchorPane.setLeftAnchor(scale, 0d);
AnchorPane.setRightAnchor(scale, 0d);
Rectangle clip = new Rectangle();
scaleContainer.setClip(clip);
clip.widthProperty().bind(scaleContainer.widthProperty());
clip.heightProperty().bind(scaleContainer.heightProperty());
ScrollPane scroll = new ScrollPane(content);
scale.translateYProperty().bind(Bindings.createDoubleBinding(() -> {
double contentHeight = content.getHeight();
double viewportHeight = scroll.getViewportBounds().getHeight();
if (contentHeight <= viewportHeight) {
return 0d;
} else {
return -scroll.getVvalue() * (contentHeight - viewportHeight);
}
}, scroll.viewportBoundsProperty(), scroll.vvalueProperty(), content.heightProperty()));
HBox root = new HBox(scaleContainer, scroll);
root.setPadding(new Insets(10));
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
I've been trying to find a way to do this online, but I haven't been able to find anything.
I want to draw an "inverse circle" with the JavaFX GraphicsContext.
These images show what I want.
Original:
With "Inverted Circle" (What I want to draw):
In an image editor I can just erase the circle area in the new layer... I don't see any functions that would do that in GraphicsContext.
I'd need to be able to choose the center point and radius of this "circle".
Thanks!
I am not very sure of directly using GraphicsContext, but you can do it using Blending.
ImageView image; // Your image
Circle mask = new Circle();
Group g = new Group();
g.setBlendMode(BlendMode.SRC_ATOP);
g.getChildren.add(image);
g.getChildren.add(mask);
Construct a circular path and use it as clip when drawing the image:
#Override
public void start(Stage primaryStage) {
Image image = new Image("https://i.stack.imgur.com/zEoW1.jpg");
double w = image.getWidth();
double h = image.getHeight();
Canvas canvas = new Canvas(w, h);
GraphicsContext gc = canvas.getGraphicsContext2D();
// draw background
gc.setFill(Color.BLACK);
gc.fillRect(0, 0, w, h);
double r = Math.min(h, w) * 2 / 5;
double cx = w / 2;
double cy = h / 2;
// create circular path
gc.beginPath();
gc.moveTo(cx - r, cy); // to first point on the circle
gc.arc(cx, cy, r, r, 180, 360);
gc.closePath();
gc.clip();
gc.drawImage(image, 0, 0);
StackPane root = new StackPane();
root.getChildren().add(canvas);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
I have some rectangles drawn on Canvas. And now I need for each rectangle an onclickListener.
But because I'm very new to android and specially Canvas, I need some help.
Anyway is it possible to add a listener?
It looks like this:
And this is my code for it:
RelativeLayout ll = (RelativeLayout) findViewById(R.id.rect);
Paint paint = new Paint();
Paint paintForSize = new Paint();
paintForSize.setColor(Color.parseColor("#FFFFFF"));
paintForSize.setTextSize(45);
Bitmap bg = Bitmap.createBitmap(480, 800, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bg);
int left = 0; // initial start position of rectangles (50 pixels from left)
int leftText =70;
int topText = 93;
int top = 50; // 50 pixels from the top
int width = 60;
int height = 60;
for(int x = 0; x < 4; x++) { // draw 4 rectangles
if(x == 0){
paint.setColor(Color.parseColor("#FF7979"));
canvas.drawText("Rec 1", leftText, topText, paintForSize);
}
if(x == 1){
paint.setColor(Color.parseColor("#FFD060"));
canvas.drawText("Rec 2", leftText, topText, paintForSize);
}
if(x == 2){
paint.setColor(Color.parseColor("#B6DB49"));
canvas.drawText("Rec 3", leftText, topText, paintForSize);
}
if(x == 3){
paint.setColor(Color.parseColor("#CB97E5"));
canvas.drawText("Rec 4", leftText, topText, paintForSize);
}
canvas.drawRect(left, top, left+width, top+height, paint);
top = (top + height + 10); // set new left co-ordinate + 10 pixel gap
topText = (topText + height + 10);
}
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
ImageView iV = new ImageView(this);
iV.setImageBitmap(bg);
ll.addView(iV,params);
Can anybody guide me through this, how should I do it?
Canvas is not a View. You cannot add listeners to them. You could create a custom View implementation. Whatever you do with the Canvas, implement that in onDraw(), which receives a Canvas as a parameter. Then add your view to a layout and give it whatever listeners you want. You may as well look into SurfaceView for drawing, which is a View.
This might help you.
Might I suggest rethinking how this is going to work. If these rectangles are going to be buttons of some sort, perhaps your better off drawing buttons in your user interface, or using images instead of the rectangles. (Sorry didnt realise this is what you were going to do in your previous question)
Have a look at: Difference between a clickable ImageView and ImageButton
You can set an eventlistener on your imageview, as mentioned in another answer. See here: Image in Canvas with touch events