JavaFX GridPane contains non defined spacing - javafx

Iam trying to add some Labels to a GridPane.
Those Labels contain ImageViews which contain some Images.
My images are .png-images and are 50 x 50 pixels big.
If my GridPane is getting to big to display it on my screen, I want to resize my Images. Iam trying this with the methods setFitWidth and setFitHeight.
Snipped:
#Override
public void start(Stage stage) {
GridPane gridPane = new GridPane();
int ySize = 5;
int xSize = 5;
int imageSize = 25;
for(int i=0 ; i<ySize ; i++) {
for(int j=0 ; j<xSize ; j++) {
ImageView imageView = new ImageView(new Image(getClass().getResourceAsStream("path.png")));
imageView.setFitWidth(imageSize);
imageView.setFitHeight(imageSize);
Label label = new Label();
label.setGraphic(imageView);
gridPane.add(label, i, j);
}
}
stage.setScene(new Scene(gridPane));
stage.show();
}
The output looks fine:
However, if imageSize is getting to small, for example 10, a horicontal spacing appears between the rows:
Is there any way to remove this? I tried to set the label sizes max-properties:
label.setMaxHeight(imageSize);
label.setMaxWidth(imageSize);
with no effect.
Is there any way to remove the spacing? Is it because the images are .png's?
Thank you

Related

Problem adding QPushButtons to my app. When I run the code, only the last button is placed in my window. The previous 8 are being overwritten

This is what I have so far. When I run the app, the last button in the array gets placed which means that the previous 8 are being stepped on.
QWidget *qwid = new QWidget(this);
QGridLayout *gl = new QGridLayout(qwid);
qwid->setLayout(gl);
QTabWidget *qtab = new QTabWidget();
qtab->addTab(qwid, "name");
QStringList buttonLbls({"button1", "button2", "button3:});
QHBoxLayout *hbox = new QHBoxLayout(qwid);
QPushButton *btnCount[3];
for(int i=0; i<3; i++)
{
btnCount[i] = new QPushButton(buttonsLbls[i], qwid);
hbox->addWidget(btnCount[i]);
qwid->setLayout(hbox);
}
You are setting two different layouts for the main widget. Remove the first (gl). Try to set the layout for the main widget and then add buttons:
qwid->setLayout(hbox);
for(int i=0; i<3; i++)
{
btnCount[i] = new QPushButton(buttonsLbls[i], qwid);
hbox->addWidget(btnCount[i]);
}
First you need to decide whether you want to have your buttons in a grid or not.
If you go with gridlayout then you can just add your widgets with the QGridLayout::addWidget and pass the correct row and column where the widget should go inside the grid. You won't need the separate horizontal layout in that case. Finally you set the gridlayout as the layout of your parent widget (qwid).
QWidget* qwid = new QWidget(this);
QGridLayout* gridLayout = new QGridLayout();
QStringList buttonLabels({"button1", "button2", "button3", "button4"});
QHash<QString, QPushButton*> buttons; // For storing button pointer for easy access
int columns = 2;
for (int n = 0; n < buttonLabels.size(); n++)
{
int column = n % columns;
int row = n / columns;
const QString& buttonLabel = buttonLabels.at(n);
QPushButton* button = new QPushButton(buttonLabel);
buttons[buttonLabel] = button;
gridLayout->addWidget(button, row, column);
}
qwid->setLayout(gridLayout);
An alternative is to use combination of horizontal and vertical layout where you create horizontal layout for each row (in a loop), add your widgets to the horizontal layout. Then add each horizontal layout inside a single vertical layout with addLayout function. Finally you set the vertical layout as the layout of your parent widget (qwid).
QWidget* qwid = new QWidget(this);
QVBoxLayout* verticalLayout = new QVBoxLayout();
QStringList buttonLabels({"button1", "button2", "button3", "button4"});
QHash<QString, QPushButton*> buttons; // For storing button pointer for easy access
int columns = 2;
int rows = columns / buttonLabels.size();
int index = 0;
for (int row = 0; row < rows; row++)
{
QHBoxLayout* rowLayout = new QHBoxLayout()
for (int col = 0; col < columns; col++)
{
const QString& buttonLabel = buttonLabels.at(index);
QPushButton* button = new QPushButton(buttonLabel);
buttons[buttonLabel] = button;
rowLayout->addWidget(button);
index++;
}
verticalLayout->addLayout(rowLayout);
}
qwid->setLayout(verticalLayout);
Another alternative is to just use the horizontal (or vertical) layout only and just add the widgets there and set the layout as the layout of your parent widget (qwid).
QWidget* qwid = new QWidget(this);
QHBoxLayout* horizontalLayout = new QHBoxLayout();
QStringList buttonLabels({"button1", "button2", "button3", "button4"});
QList<QPushButton*> buttons; // For storing button pointer for easy access
for (const QString& buttonLabel : buttonLabels)
{
QPushButton* button = new QPushButton(buttonLabel);
buttons << button;
horizontalLayout->addWidget(button);
}
qwid->setLayout(horizontalLayout);
It depends on what you actually want to do with your widgets.

How to make pyramid patterns of Circle shape using GridPane in javafx

i wanna create pyramid left,right,center angle, using Circle shape in GridPane, i have already done with the left angle, but spent 2 days in creating right and center angle with no luck.
i will be thankful if anyone knows or can give me some algo ideas please help me!
Output already done left angle
With the following code
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
Circle circle = new Circle();
circle.setStroke(Paint.valueOf(Color.BLACK.toString()));
circle.radiusProperty().bind(ballsModel.radiusProperty());
circle.strokeWidthProperty().bind(ballsModel.strokeProperty());
circle.fillProperty().bind(Bindings.createObjectBinding(() -> Paint.valueOf(ballsModel.getColor().name())));
grid.addRow(i, circle);
}
}
Need to figure out following patterns:
center angle
right angle
an example for the pyramid part
package pyramid;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class Pyramid extends Application {
void createPyramid(){
gridPane.setHgap(5);
gridPane.setVgap(5);
int center = 4 ;
for (int row = 0; row <= 4; row++ ) {
int range = (1 +(2* row));
int startColumn = center-range/2 ;
for(int i = 0 ; i<range; i++){
Circle circle = new Circle(20,javafx.scene.paint.Color.BLUE);
gridPane.add(circle,startColumn+i , row);
}
}}
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
root.getChildren().add(gridPane);
this.createPyramid();
Scene scene = new Scene(root, 600, 600);
primaryStage.setTitle("Pyramid");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}}

Problems removing custom Qgraphicsitem from Qgraphicsscene

I have subclassed both a Qgraphicsscene and a Qgraphicsitem, it seems it works but trying to remove the items by subclass recognition don't works.
This delete the items:
void debugSceneItemscuatrobis()
{
QList<QGraphicsItem *> allitems = items();
foreach(auto item, allitems) {
removeItem(item);
}
}
But this doesn't, it recognizes there are items but doesn't remove them, tryed different posseibilities but couldn't make it works.
void debugSceneItemscuatrotris()
{
QList<QGraphicsItem *> allitems = items();
foreach(auto item, allitems) {
if(item->type() == chord::Type) {
removeItem(item);
delete item;
}
}
}
This is how the items were added by the qgraphicsitem subclass:
void chord::addchord(QPointF sp)
{
scene()->addLine(sp.x(), sp.y(), sp.x()+10, sp.y()+10);
QList<int> midics = {10, 30, 40};
for(int i = 0; i < midics.length(); i++)
{
QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem("n");
item->setFont(QFont("omheads", 20));
item->setPos(sp.x(), sp.y()+midics[i]);
scene()->addItem(item);
coso.append(item);
}
}
Sorry, I'm very newbie and no programmer, those are my first subclasses. Someone knows how it could be approached? Thanks. :-)
Without seeing more of your code I'm only guessing. But that guess would be that when you remove an item of type chord you are still able to see the various QGraphicsItems that were added to the scene in chord::addchord. If so it's probably due to the lack of any parent/child relationship between the chord and those items: from the documentation for QGraphicsScene::removeItem(item)...
Removes the item item and all its children from the scene.
Try creating the parent/child relationship explicitly by changing your chord:addchord implementation to...
void chord::addchord (QPointF sp)
{
auto *line = scene()->addLine(sp.x(), sp.y(), sp.x() + 10, sp.y() + 10);
line->setParentItem(this);
QList<int> midics = { 10, 30, 40 };
for (int i = 0; i < midics.length(); i++)
{
QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem("n", this);
item->setFont(QFont("omheads", 20));
item->setPos(sp.x(), sp.y() + midics[i]);
scene()->addItem(item);
coso.append(item);
}
}
It might not solve all of the issues but should (hopefully) head you in the right direction.

JavaFX rotate rectangle about center?

I'm trying rotate a rectangle around its center. The rotation is being drawn to a canvas using the GraphicsContext ie gc. Here is my draw code.
gc.save();
gc.translate(center.x, center.y);
gc.rotate(this.angle);
gc.strokeRect(0,0, this.width, this.height);
gc.restore();
This moves the rectangle to its center but then it rotates the rectangle around its top left point. I tried subtracting half the length and width of the sides but that just made it fly all over the place. I suck at math maybe someone here who is better can show me what I'm doing wrong.
I also have stored all four points (corners) of the rectangle if that information is needed.
Thanks,
Joe
A rotation around a specified point needs to be composed from translate transformations and rotations around the origin as follows:
Use translation to move the center of the rotation to the origin.
rotate around the origin
use inverse translation to the first translation
The third part is missing from your code.
Example
#Override
public void start(Stage primaryStage) throws Exception {
Canvas canvas = new Canvas(400, 400);
double x = 50;
double y = 100;
double width = 100;
double height = 200;
GraphicsContext gc = canvas.getGraphicsContext2D();
double rotationCenterX = (x + width) / 2;
double rotationCenterY = (y + height) / 2;
gc.save();
gc.translate(rotationCenterX, rotationCenterY);
gc.rotate(45);
gc.translate(-rotationCenterX, -rotationCenterY);
gc.fillRect(0, 0, width, height);
gc.restore();
Scene scene = new Scene(new Group(canvas));
primaryStage.setScene(scene);
primaryStage.show();
}
You could also simply use a Rotate with a specified pivot to achieve the desired effect:
#Override
public void start(Stage primaryStage) throws Exception {
Canvas canvas = new Canvas(400, 400);
double x = 50;
double y = 100;
double width = 100;
double height = 200;
GraphicsContext gc = canvas.getGraphicsContext2D();
double rotationCenterX = (x + width) / 2;
double rotationCenterY = (y + height) / 2;
gc.save();
gc.transform(new Affine(new Rotate(45, rotationCenterX, rotationCenterY)));
gc.fillRect(0, 0, width, height);
gc.restore();
Scene scene = new Scene(new Group(canvas));
primaryStage.setScene(scene);
primaryStage.show();
}
It's just so simple, like below.
Rectangle rect = new Reactangle(20, 20, 100, 50);
rect.setRotate(30); //rotate the rectangle around its center by 30 degrees.

JavaFX Rectangles inside FlowPane

I have a problem to draw this image (below link) I had his in the middle of flow pane but only half of this! How to draw full image>?
http://s16.postimg.org/lrus832dx/Capture2.png
http://s27.postimg.org/hsujjp1s3/Capture1.png
Ok, I think I understand your problem now. I suggest you to use a GridPane instead, then you can do it this way:
#Override
public void start(Stage primaryStage) {
GridPane root = new GridPane();
int rows = 2;
int columns = 2;
int rectangleWidth = 50;
int rectangleHeight = 50;
root.setMaxSize(rectangleWidth*columns, rectangleHeight*rows);
for(int row = 0; row < rows; row++)
{
for(int col= 0; col< columns; col++)
{
Rectangle rectangle = new Rectangle(rectangleWidth, rectangleHeight);
root.add(rectangle, col, row);
if(row % 2 == 0)
{
rectangle.setFill(col % 2 == 0 ? Color.ORANGE : Color.BLACK);
}
else
{
rectangle.setFill(col % 2 != 0 ? Color.ORANGE : Color.BLACK);
}
}
}
Scene scene = new Scene(new StackPane(root), 700, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
We need to wrap the GridPane containing the Rectangles in a StackPane to center it in its parent.

Resources