Javafx button text not showing - java

I'm currently creating a layout in JavaFX. However, the text of my buttons is showing in some places and for some buttons the text is just showing as '...'.
I want to display the whole text in the buttons while keeping the window size as 500x500.
Here's my code, I'm creating 10 buttons and only some of them are showing their text. Is there any way to set the button sizes constant throught the layout while also displaying their text?
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class MainGUI extends Application {
private Button[] buttons=new Button[10];
private Stage window;
private GridPane layout;
public int count=3;
#Override
public void start (Stage primaryStage)
{
window=primaryStage;
layout=new GridPane();
layout.setPadding(new Insets(100));
layout.setVgap(10);
layout.setHgap(10);
for(int i=0;i<10;i++)
{
buttons[i]=new Button();
}
buttons[0].setText("y=0.5x");
buttons[1].setText("y=x");
buttons[2].setText("y=2x");
buttons[3].setText("y=0.1x^2");
buttons[4].setText("y=x^2");
buttons[5].setText("y=10x^2");
buttons[6].setText("y=3 sin(x pi/10)");
buttons[7].setText("y=6 sin(x pi/10)");
buttons[8].setText("y=6 sin(x pi/5)");
buttons[9].setText("y= 5 sin(x pi/10) + (5/3)sin(3x pi/10) + sin(x pi/2) + (5/7)sin(7x pi/10)");
for(int j=0;j<10;j++)
{
if (count==3)
{
count=0;
}
if(j<=2)
{
GridPane.setConstraints(buttons[j],count,0);
}
else if ((j>2) && (j<=5))
{
GridPane.setConstraints(buttons[j],count,1);
}
else if((j>5) && (j<=8))
{
GridPane.setConstraints(buttons[j],count,2);
}
else if((j>8) && (j<=9))
{
GridPane.setConstraints(buttons[j],1,3);
}
count++;
}
layout.getChildren().addAll(buttons);
Scene scene=new Scene(layout,600,600);
window.setScene(scene);
window.show();
}
public static void main(String[] args)
{
launch(args);
}
}

This is how it looks with 0 insets :
As you can see it is quiet tight.
An easy alternative would be to make the last long button span over two columns:
GridPane.setConstraints(buttons[j],1,3,2,1);
Which results in
For more control over the layout consider using some child panes. For example:

Related

How to set minimum diameter in jfxtras CircularPane?

How to set minimum diameter to jfxtras circularpane. For example take a look at following code,
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import jfxtras.scene.layout.*;
/**
* AssistiveBall
*/
public class AssistiveBall extends Application
{
#Override
public void start(Stage pStage) throws Exception
{
StackPane root = new StackPane();
CircularPane pane = new CircularPane();
Scene scene = new Scene(root, 800, 600);
Button btn = new Button("Center");
Button[] buttons = new Button[13];
for (int i = 0; i < buttons.length; i++)
{
buttons[i] = new Button("" + i);
}
pane.getChildren().addAll(buttons);
btn.setOnAction(e -> {
if(pane.isVisible())
{
pane.setVisible(false);
}
else
{
pane.setVisible(true);
}
});
root.getChildren().add(pane);
root.getChildren().add(btn);
pStage.setScene(scene);
pStage.setTitle("Assistive Ball");
pStage.show();
}
public static void main( String[] args )
{
AssistiveBall.launch(args);
}
}
Here here code if fine, but if i use just 3 buttons it starts appear one on another, So how to set minimum diameter or there is any another way to do this ?
Thanks.
Version 11-r3-SNAPSHOT has changed certain methods like computeChainDiameter and determineBeadDiameter to protected, so you can override them and tune the output.

change BackGround color of specific elements in a listView (JavaFx)

i'm working on a project and i'd like to find a way to change the background color of some elements in a listView. i've find a way to add css style class to the listView in general but not to specific elements .
Also , i've heard about cell factory but I dont know if cell factory can adapt during the programme or just set up things at the begging
(i have a listView of an object that I call player , and I want that , when the player in the listView get enough points , his name becomes red)
is there a way to do something like this ?
ListView<Players> listview = ...;
for(Player p : listView){
p.addListener(//change color to red)
}
Thanks
I would use ObservableList and addListener to the given List.
Sample code:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class App extends Application {
private StackPane main;
private ListView<Player> players;
#Override
public void start(Stage stage) {
main = new StackPane();
var scene = new Scene(main, 640, 480);
players = new ListView<Player>();
ObservableList<Player> playerObjs = FXCollections.observableArrayList (
new Player("A", 50),
new Player("B", 30),
new Player("C", 60),
new Player("D", 5),
new Player("E", 0)
);
players.setItems(playerObjs);
playerObjs.addListener(new ListChangeListener<Player>() {
#Override
public void onChanged(Change<? extends Player> change) {
updateView();
}
});
main.getChildren().add(players);
stage.setScene(scene);
stage.show();
}
public void updateView() {
for(int i = 0; i < players.getItems().size(); i++) {
if(players.getItems().get(i).getHp() < 10) {
players.getItems().get(i).setBackground(...);
}
}
}
public static void main(String[] args) {
launch();
}
}
Now, everytime the list changes, it calls updateView(), which if some condition holds, will set the given item Background to some value.
Let me know if that helped.

Flood fill using java Pane - JAVA

Hi I am supposed to create function which would do flood fill on a Pane containing Shapes using Java. It is supposed to behave just like MSPaint, I dont need to later move rectangles Lines or other shapes. I was thinking converting Pane into Image and then work with pixels and then clear all Panes children and insert it as a image but I cant make it work.
code example:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Paint extends Application {
public static void main(String[] args) {
launch(args);
}
private Pane pane;
#Override
public void start(Stage primaryStage) {
pane= new Pane();
primaryStage.setTitle("Fill");
Scene scene = new Scene(pane,500,600);
primaryStage.setScene(scene);
primaryStage.show();
pane.setOnMousePressed((e)->{
doFill(e.getX(),e.getY());
});
//RECT 1
Rectangle rect1=new Rectangle(1,100,200,300);
rect1.setStroke(Color.BLACK);
rect1.setStrokeWidth(2);
rect1.setFill(Color.WHITE);
//RECT 2
Rectangle rect2=new Rectangle(50,150,200,400);
rect2.setStroke(Color.BLACK);
rect2.setStrokeWidth(2);
rect2.setFill(Color.WHITE);
//LINE
Line line=new Line(0,0,200,550);
rect2.setStroke(Color.BLACK);
rect2.setStrokeWidth(2);
pane.getChildren().addAll(rect1,rect2,line);
}
private void doFill(double eventX, double eventY){
//**TODO**
}
}
Got managed to do that function even though its a bit messy. So for everyone who is getting anxious over this:
private void doFill(double eventX, double eventY,boolean b){
WritableImage i=pane.snapshot(new SnapshotParameters(), null);
ArrayList<Integer> pozicie=new ArrayList<Integer>();
ArrayList<Character> strany=new ArrayList<Character>();
pozicie.add((int)eventX);
pozicie.add((int)eventY);
int c=i.getPixelReader().getColor((int)eventX,(int)eventY).hashCode();
if(c==usedColor.hashCode()){
//System.out.println("same color");
return;}
strany.add('a');
while(pozicie.size()!=0){
char strana=strany.remove(0);
int x=pozicie.remove(0);
int y=pozicie.remove(0);
i.getPixelWriter().setColor(x, y, usedColor);
if(strana=='d'){
//iba dole
if(y<pane.getHeight()-2 && i.getPixelReader().getColor(x, y+1).hashCode()==c){
pozicie.add(x);
pozicie.add(y+1);
strany.add('d');
}
}
else if(strana=='u'){
//iba hore
if( y>100 && i.getPixelReader().getColor(x, y-1).hashCode()==c){
pozicie.add(x);
pozicie.add(y-1);
strany.add('u');
}
}
else{
if(x>2 && i.getPixelReader().getColor(x-1, y).hashCode()==c){
pozicie.add(x-1);
pozicie.add(y);
strany.add('l');
}
if(x<pane.getWidth()-2 && i.getPixelReader().getColor(x+1, y).hashCode()==c){
pozicie.add(x+1);
pozicie.add(y);
strany.add('r');
}
if( y>101 && i.getPixelReader().getColor(x, y-1).hashCode()==c){
pozicie.add(x);
pozicie.add(y-1);
strany.add('u');
}
if(y<pane.getHeight()-2 && i.getPixelReader().getColor(x, y+1).hashCode()==c){
pozicie.add(x);
pozicie.add(y+1);
strany.add('d');
}
}
}
pane.getChildren().clear();
pane.getChildren().add(new ImageView(i));
}

Java change Label image

I have two different StackPanes with HBoxes I want to change the image of a label in the second StackPane with a Label(MouseListener) in the first StackPane I think the problem is that the Label doesn't gets repainted or reloaded
First StackPane:
Label label= new Label("",new ImageView(ClearSpace));
label.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent event) -> {
HotBar hb = new HotBar();
if(hb.getX1() == 0){
hb.setImageX1(5);
}
event.consume();
});
Second StackPane(HotBar):
public Label x1;
Image image= new Image(getClass().getResourceAsStream("/resources/images/Test.png"));
...
Label x1 = new Label("",new ImageView(image));
...
public void setImage(int i){
if(i == 5){
x1.setGraphic(new ImageView(image2));
}
}
I think these are the importantst parts of hte code
setImage() is definetly working if you use it below Label x1 = ... it works
In your EventHandler you create a new instance of HotBar on which you do changes, but this instance is not linked to the scene.
Instead you should pass the instance of HotBar into the other class and use that in your event handler.
package helloworld;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
/**
* Created by matt on 3/22/16.
*/
public class SwapLabel extends Application {
int i = 0;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
Pane root = new Pane();
Image img1 = new Image("http://www.logotemplater.com/freelogostemplates/voope-free-logo-template.png", true);
Image img2 = new Image("http://www.logotemplater.com/freelogostemplates/zoozz-vector-logo-template-sample.png", true);
Label l = new Label("", new ImageView(img1));
l.addEventHandler(MouseEvent.MOUSE_CLICKED, e->{
i = (i+1)%2;
if(i==0){
l.setGraphic(new ImageView(img1));
}else{
l.setGraphic(new ImageView(img2));
}
});
root.getChildren().add(l);
primaryStage.setScene(new Scene(root, 200, 200));
primaryStage.show();
}
}
This appears to be what you are trying to do, but this works. So most likely something else is happening.

How to know if the resizing of a window is done from the left or from the right?

I am using JavaFX to build a GUI and I'm having problems on knowing the mouse location when resized. The idea is that if a mouse gets on the very edge of the GUI it changes to a double sided arrow indicating that you can now press the mouse and resize the window.
I need the location of the mouse pointer on this edge, but I don't know how to do that. I need to know in which direction the window is resized.
Updated Added new options and discussed pros and cons.
This is tricky. The issue is that the window keeps track of its top, left, width, and height. When it is resized from the right or bottom, things are easy enough: the width or height change. But when it is resized from the left, both x and width must change. These two changes do not happen atomically, as x and width are stored as two independent properties.
The first approach to this is to keep track of the mouse coordinates, and just see if it's in the left half or the right half. (Obviously you can do the same with the height.) This approach is independent of any implementation details, but the user can cause it to fail by being extremely careful with the mouse. If you move the mouse to the right edge of the window to the exact pixel of the window boundary, then resize, you can see incorrect output.
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
class MouseLocation {
double x,y ;
}
MouseLocation mouseLocation = new MouseLocation();
scene.setOnMouseMoved(event -> {
mouseLocation.x = event.getX();
mouseLocation.y = event.getY();
});
primaryStage.widthProperty().addListener((obs, oldWidth, newWidth) -> {
if (mouseLocation.x < primaryStage.getWidth() / 2) {
System.out.println("Resized from left");
} else {
System.out.println("Resized from right");
}
});
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The second approach is to keep track of the last known horizontal range of the window (minX and maxX), and update that range when the width changes. Then you can check to see whether the minX or maxX has changed. The problem with this approach is that it's dependent on undocumented implementation details. It appears (on my system, using the current version, etc) that when the window is resized from the left, x is changed first, then the width is changed. If that were to change in a subsequent release, the following would break:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
class MutableDouble {
double value ;
}
MutableDouble windowLeftEdge = new MutableDouble();
primaryStage.widthProperty().addListener((obs, oldWidth, newWidth) -> {
if (primaryStage.getX() == windowLeftEdge.value) {
System.out.println("Resized from right");
} else {
System.out.println("Resized from left");
}
windowLeftEdge.value = primaryStage.getX() ;
});
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The third approach (that I can think of) is to coalesce changes that happen quickly into a single change. This is a bit tricky to program correctly, so instead of doing it from scratch, I used the third party ReactFX framework which models "event streams" and has a built-in mechanism for combining events that happen in quick succession. This is probably the most robust of the three solutions presented here, but at the cost of either a degree of complexity, or the inclusion of an external framework.
import java.time.Duration;
import org.reactfx.Change;
import org.reactfx.EventStream;
import org.reactfx.EventStreams;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ObservableValue;
import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class ReactFXVersion extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
ObservableValue<Bounds> windowBounds = Bindings.createObjectBinding(() ->
new BoundingBox(primaryStage.getX(), primaryStage.getY(), primaryStage.getWidth(), primaryStage.getHeight()),
primaryStage.xProperty(), primaryStage.yProperty(), primaryStage.widthProperty(), primaryStage.heightProperty());
EventStream<Change<Bounds>> bounds = EventStreams.changesOf(windowBounds)
.reduceSuccessions((previousChange, nextChange) ->
new Change<>(previousChange.getOldValue(), nextChange.getNewValue()),
Duration.ofMillis(10));
bounds.subscribe(boundsChange -> {
Bounds newBounds = boundsChange.getNewValue();
Bounds oldBounds = boundsChange.getOldValue();
if (newBounds.getWidth() != oldBounds.getWidth()) {
if (newBounds.getMinX() != oldBounds.getMinX()) {
System.out.println("Resized from left");
} else if (newBounds.getMaxX() != oldBounds.getMaxX()) {
System.out.println("Resized from right");
}
}
if (newBounds.getHeight() != oldBounds.getHeight()) {
if (newBounds.getMinY() != oldBounds.getMinY()) {
System.out.println("Resized from top");
} else if (newBounds.getMaxY() != oldBounds.getMaxY()) {
System.out.println("Resized from bottom");
}
}
});
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Categories