I am trying to set up my javafx scene, but i have failed miserable.
basically what i am trying to do is as per attached photo.
I have tried to set up a gridpane and then position another gridpane withing it so that I can set up the boxes and labels however this is not working properly.
I do not want to use FXML.
can you guys recommend how to go about this set up.
The JavaFx SceneBuilder is a good tool to create Layouts like the one you want to have. Take a look at the official website. The tool creates a FXML file which you can load in your applications start() method using:
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("application.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
Another resource where you can get familiar with SceneBuilder is the #Java and #OracleLearning channels on Youtube.
This code worked for me in setting up the given arrangement:
GridPane outerPane = new GridPane();
GridPane innerPane1 = new GridPane();
GridPane innerPane2 = new GridPane();
HBox l = new HBox(new Label("Label"));
l.setAlignment(Pos.CENTER);
outerPane.add(l, 1, 1);
innerPane1.add(new Circle(20, Color.LIGHTCORAL), 1, 1);
outerPane.add(innerPane1, 2, 1);
innerPane2.add(new Button("Button"), 1, 1);
innerPane2.add(new Label(" Label"), 2, 1);
innerPane2.add(new Button("Button"), 1, 2);
innerPane2.add(new Label(" Label"), 2, 2);
innerPane2.add(new Button("Button"), 1, 3);
innerPane2.add(new Label(" Label"), 2, 3);
GridPane.setMargin(innerPane2, new Insets(5,5,5,5));
outerPane.add(innerPane2, 1, 2);
outerPane.setAlignment(Pos.CENTER);
Drop any further confusions in the comments :)
Related
The solution for centering any subview within a parent is usually simple, however, it doesn't seem to work in my case.
I'm working with a UICollectionView and have added a Header class programmatically. I have this constructor, where I also try to center the label within the screen:
[Export("initWithFrame:")]
public Header(System.Drawing.RectangleF frame) : base(frame)
{
label = new UILabel
{
Frame = new System.Drawing.RectangleF(frame.Size.Width / 2, 50, 200, 50),
BackgroundColor = UIColor.Clear,
TextColor = UIColor.White,
Font = UIFont.FromName("HelveticaNeueLTStd-ThCn", 35f),
Text = DateTime.Now.ToString("Y")
};
AddSubview(label);
}
And I initialize the class inside the UICollectionViewSource 's constructor like this:
public MyCollectionViewDataSource(MainController mainController, DateTime currentDate)
{
try
{
controller = mainController;
new Header(new RectangleF(0, 0, (float)mainController.View.Frame.Size.Width, 200));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ex.StackTrace);
}
}
What exactly am I missing because this usually works in other instances but seems to fail here?
This is what it looks like :
I found an explanation here iOS Layout Gotchas by Adam Kemp which helped me resolve this issue.
The first solution
One very common mistake I made was adding the layout definition code in the constructor, instead of doing it in the rightful place : the LayoutSubviews override in this case.
Giving the label the frame size in the constructor assumes a static size set at the time of construction, which may later change depending on the screen size.
The second solution
He explains that :
Frame sets the position of a view within its parent while Bounds is in the coordinate system of the view itself (not its parent).
So, to center the UILabel, I used bounds and center together and this worked for me.
[Export("initWithFrame:")]
public Header(CGRect bounds) : base(bounds)
{
label = new UILabel
{
BackgroundColor = UIColor.Clear,
TextColor = UIColor.White,
Font = UIFont.FromName("HelveticaNeueLTStd-ThCn", 35f),
Text = DateTime.Now.ToString("Y"),
TextAlignment = UITextAlignment.Center
};
rectangle = bounds;
AddSubview(label);
}
public override void LayoutSubviews()
{
base.LayoutSubviews();
label.Bounds = new CGRect (rectangle.Size.Width / 2, 50, 200, 50);
label.Center = new PointF((float)rectangle.Size.Width/2,50);
}
I am able to add ImageIcons to a JTextPane, but when I add them they show up in the center of the JTextPane. I can't find a way to control where they are placed on the JTextPane. Can someone please help me with this?
This method is making the JTextPane:
private void loadTextPanel(JPanel contentPane) {
chatLogPanel = new JPanel();
chatLogPanel.setLayout(null);
EmptyBorder eb = new EmptyBorder(new Insets(10, 10, 10, 10));
DefaultStyledDocument document = new DefaultStyledDocument();
chatLog = new JTextPane(document);
chatLog.setEditorKit(new WrapEditorKit());
chatLog.setBorder(eb);
chatLog.setMargin(new Insets(5, 5, 5, 5));
chatLogScrollPane = new JScrollPane(chatLog);
addComponent(chatLogPanel, chatLogScrollPane, 0, 0, 500, 240);
addComponent(contentPane, chatLogPanel, 0, 40, 500, 240);
}
This is the code I'm using to add a string to the Panel:
private static void appendToChatLog(JTextPane tp, String msg, Color c) {
chatLog.setEditable(true);
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);
aset = sc.addAttribute(aset, StyleConstants.FontFamily, "Lucida Console");
aset = sc.addAttribute(aset, StyleConstants.Alignment, Integer.valueOf(3));
int len = tp.getDocument().getLength();
tp.setCaretPosition(len);
tp.setCharacterAttributes(aset, false);
tp.replaceSelection(msg);
chatLog.setEditable(false);
}
And this is what I'm currently using to add the image to the JTextPane:
BufferedImage image = generateBufferedImage(message.getImage());
Icon icon = new ImageIcon(image);
StyleContext context = new StyleContext();
StyledDocument document = (StyledDocument) chatLog.getDocument();
Style labelStyle = context.getStyle(StyleContext.DEFAULT_STYLE);
JLabel label = new JLabel(icon);
StyleConstants.setComponent(labelStyle, label);
try {
document.insertString(document.getLength(), "Ignored", labelStyle);
} catch (BadLocationException badLocationException) {
badLocationException.printStackTrace();
}
To insert a component to a JTextPane, and display it like a character, use the insertComponent method.
To insert an Icon instead, use the insertIcon method.
Quite intuitive isn't it ;)
I am developing an application in which i am showing a image followed by text followed by image again horizontally in table layout.
I am creating the table layout programmatically as:
for(i = 0; i < arrayList.size(); i++){
/* Find Tablelayout defined in main.xml */
TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
tableLayout.setStretchAllColumns(true);
/* Create a new row to be added. */
TableRow tableRow = new TableRow(this);
tableRow.setId(i);
tableRow.setClickable(true);
tableRow.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
v.setBackgroundColor(Color.GRAY);
}
});
tableRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT));
/* Create a Button to be the row-content. */
ImageView imageView1 = new ImageView(this);
if(arrayList.get(i).getImage().equalsIgnoreCase("Y")){
// setImage
}
imageView1.setPadding(5, 5, 5, 5);
imageView1.setLayoutParams(new TableRow.LayoutParams(100, 100));
tableRow.addView(imageView1);
TextView textViewName = new TextView(this);
textViewName.setText(arrayList.get(i).getName());
textViewName.setPadding(5, 5, 5, 5);
textViewName.setGravity(Gravity.CENTER_VERTICAL);
textViewName.setTextSize(15);
textViewName.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.MATCH_PARENT,7));
tableRow.addView(textViewName);
ImageView imageView2 = new ImageView(this);
imageView2.setImageDrawable(getResources().getDrawable(R.drawable.icon));
imageView2.setPadding(25, 25, 25, 25);
imageView2.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.MATCH_PARENT,1));
tableRow.addView(imageView2);
tableLayout.addView(tableRow, new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.MATCH_PARENT));
View horizontalLine = new View(this);
horizontalLine.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, 1));
horizontalLine.setBackgroundColor(Color.rgb(50, 50, 50));
tableLayout.addView(horizontalLine);
}
With the help of this i am getting the out put as image 1.
But i need the out put as image 2.
The difference between image 1 and 2 is the red line. I am getting the line with the help of drawing view but that covers whole width. I need a line which is as same as red in image 2. In center and of fix width.
Please suggest me what changes or steps i follow. Need your valuable suggestion.
You can set the color using setBackgroundColor method.
horizontalLine.setBackgroundColor(Color.RED);
Edit :
You can horizontal line of fixed length and in center.
Add the TableRow
Define layout weight for View
Add the View in TableRow
Add the tableRow in Table layout
View horizontalLine = new View(this);
// Set weight
TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, 10,0.7f);
horizontalLine.setLayoutParams(params);
TableRow tr = new TableRow(this);
TableLayout.LayoutParams tableRowParams= new TableLayout.LayoutParams
(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
// Set margin
int leftMargin=20;
int topMargin=2;
int rightMargin=20;
int bottomMargin=2;
tableRowParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
tr.setLayoutParams(tableRowParams);
// Add View in tr
tr.addView(horizontalLine);
//Add tr in Table
tableLayout.addView(tr);
You can see the output :
Hope it helps ツ
I have a TextField in my JavaFX application. I want to programmatically display a message on the right side of the text (like the validation message). I thought of using Popup and setting the Label with message in that Popup. But I'm not sure how I can position this to the right side of the text field. Below is the sample code for this. Can you please help me with this?
public void start(Stage primaryStage) {
primaryStage.setTitle("JavaFX Welcome");
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25, 25, 25, 25));
Text scenetitle = new Text("Welcome");
scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20));
grid.add(scenetitle, 0, 0, 2, 1);
Label userName = new Label("User Name:");
grid.add(userName, 0, 1);
TextField userTextField = new TextField();
grid.add(userTextField, 1, 1);
Label pw = new Label("Password:");
grid.add(pw, 0, 2);
PasswordField pwBox = new PasswordField();
grid.add(pwBox, 1, 2);
Label label=new Label();
label.setText("This is an error message");
final Text actiontarget = new Text();
grid.add(actiontarget, 1, 6);
final Popup popup = new Popup();
popup.getContent().add(label);
//Want to display this popup to the right of the userTextField.
Scene scene = new Scene(grid, 300, 275);
primaryStage.setScene(scene);
primaryStage.show();
}
After showing the stage, do
Bounds userTextFieldBounds = userTextField.getBoundsInLocal();
Point2D popupLocation = userTextField.localToScreen(userTextFieldBounds.getMaxX(), userTextFieldBounds.getMinY());
popup.show(userTextField, popupLocation.getX(), popupLocation.getY());
The localToScreen(...) method was introduced in Java 8; if you are in an earlier version you will need
Bounds userTextFieldBounds = userTextField.getBoundsInLocal();
Point2D popupLocation = userTextField.localToScene(userTextFieldBounds.getMaxX(), userTextFieldBounds.getMinY());
popup.show(userTextField,
popupLocation.getX()+scene.getX()+primaryStage.getX(),
popupLocation.getY()+scene.getY()+primaryStage.getY());
In my current application I have created a ScrollPane with an AnchorPane as content. Depending on the actions of the user this AnchorPane will be filled with more or less images for which I use a Canvas(necessary for drawing more information on the image).
However when I scroll through the ScrollPane, all the child images are still being repainted even when they aren't inside the ViewPort. Has anyone else had this problem or a solution for this?
screenshot:
https://dl.dropboxusercontent.com/u/51537629/images%20drawn%20outside%20of%20viewport.png
Initialization of the scrollpane:
iconPane = new AnchorPane();
iconPane.setStyle("-fx-background-color: white; -fx-border-color: gray;");
iconPane.setMinHeight(546);
iconPane.setMinWidth(814);
scrollpane = new ScrollPane();
scrollpane.setContent(iconPane);
scrollpane.setVisible(false);
AnchorPane.setTopAnchor(scrollpane, 13.0);
AnchorPane.setBottomAnchor(scrollpane, 13.0);
AnchorPane.setLeftAnchor(scrollpane, 13.0);
AnchorPane.setRightAnchor(scrollpane, 13.0);
Creation of an icon:
private VBox createIconPane(TaskInformation tinfo) {
VBox vbox = new VBox();
Canvas canvas = new Canvas(75, 75);
GraphicsContext gc = canvas.getGraphicsContext2D();
Image im;
if (tinfo.getCurrent() != null) {
if (tinfo.isCurrentStop()) {
String status = utilities.getCurrentTaskVersion(tinfo.getTask()).getStatus();
if (status.equals("finished")) {
im = new Image(this.getClass().getClassLoader().getResourceAsStream("dna-current.png"));
} else if (status.equals("failed")) {
im = new Image(this.getClass().getClassLoader().getResourceAsStream("dna-failed.png"));
} else {
im = new Image(this.getClass().getClassLoader().getResourceAsStream("dna-processing.png"));
}
} else {
im = new Image(this.getClass().getClassLoader().getResourceAsStream("dna-current.png"));
}
} else {
im = new Image(this.getClass().getClassLoader().getResourceAsStream("dna-excluded.png"));
}
gc.drawImage(im, 5, 5);
gc.setStroke(Color.GREEN);
gc.strokeText(tinfo.getFinished() + "", 59, 15);
gc.setStroke(Color.RED);
gc.strokeText(tinfo.getFailed() + "", 59, 28);
gc.setStroke(Color.BLUE);
gc.strokeText(tinfo.getProcessing() + "", 59, 41);
Label namelabel = new Label(tinfo.getTask().getName());
namelabel.setLayoutX(0);
namelabel.setLayoutY(68);
vbox.getChildren().addAll(canvas,
return vbox;
}
Addition of all icons to the view:
private void createChildIcon(TaskInformation tinfo) {
VBox taskicon = createIconPane(tinfo);
taskicon.setLayoutX((tinfo.getTask().getLevel() - 6) / 2 * 120 + 5);
if (tinfo.getTask().getLevel() <= levelLastAddedTask && maxYCoor != 5) {
maxYCoor += 95;
}
levelLastAddedTask = tinfo.getTask().getLevel();
taskicon.setLayoutY(maxYCoor);
iconPane.getChildren().add(taskicon);
for (int count = 0; count < tinfo.getChildren().size(); count++) {
createChildIcon(tinfo.getChildren().get(count));
}
}
JDK: 7, but it can be compiled as older versions as well
JFX: 2.2.21
After some testing with one of my colleagues we discovered that it must be a Windows issue. It works perfectly on Linux, but not on Windows.
Try adding VM option "-Dprism.order=j2d". This is a work-around rather than a solution because it is replacing your hardware accelerated graphic pipeline with a software pipeline. If this works, add VM option "-Dprism.verbose=true" so that we can see what hardware was problematic.
I added a bug in the JavaFX Issue Tracker: https://javafx-jira.kenai.com/browse/RT-31044.