Trying to achieve:
Text Field 1 and Text Field 3 should occupy all the available free space
Button 1 and Button 2 should have same width
Issue:
Text Field 1 and Text Field 3 are NOT occupying all the available free space (though they are growing once Label is completely displayed)
Here is the screen shot:
// Removed imports for brevity
public class GridPaneTest extends Application
{
#Override
public void start(Stage primaryStage)
{
primaryStage.setTitle("GridPane Test");
GridPane gridPane = new GridPane();
// gridPane.setGridLinesVisible(true);
gridPane.setHgap(5);
gridPane.setVgap(5);
gridPane.setPadding(new Insets(5));
TextField tf1 = new TextField("Text Field 1");
GridPane.setHgrow(tf1, Priority.ALWAYS);
gridPane.add(tf1, 0, 0);
TextField tf2 = new TextField("Text Field 2");
GridPane.setHgrow(tf2, Priority.NEVER);
gridPane.add(tf2, 1, 0);
Button button1 = new Button("Button 1");
button1.setMaxWidth(140);
GridPane.setHgrow(button1, Priority.NEVER);
GridPane.setHalignment(button1, HPos.RIGHT);
gridPane.add(button1, 2, 0);
TextField tf3 = new TextField("Text Field 3");
GridPane.setHgrow(tf3, Priority.ALWAYS);
gridPane.add(tf3, 0, 1, 2, 1);
Button button2 = new Button("Button 2 Button 2");
button2.setMaxWidth(140);
GridPane.setHgrow(button2, Priority.NEVER);
GridPane.setHalignment(button2, HPos.RIGHT);
gridPane.add(button2, 2, 1);
Label label1 = new Label(
"Label 1 Label 1 Label 1 Label 1 Label 1 Label 1 Label 1 Label 1 Label 1 Label 1 Label 1");
GridPane.setHgrow(label1, Priority.ALWAYS);
gridPane.add(label1, 0, 2, 3, 1);
primaryStage.setScene(new Scene(gridPane));
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
According to GridPane documentation
if an application needs to explicitly control the size of rows or columns, it may do so by adding RowConstraints and ColumnConstraints objects to specify those metrics
gridPane.getColumnConstraints()
.addAll(new ColumnConstraints(), new ColumnConstraints(),
new ColumnConstraints(140) /* Control the third column size */);
Screen shot:
Related
I'm making a notepad application using JavaFX which includes a font selector window. The font selector includes a textfield within a gridpane layout which functions as a sample of what the selected font options will look like.
Font selector:
However, if the font chosen is taller than the text field, the field stretches to fit the text, distorting the window.
Distorted font selector:
I want the sample textfield to remain the same size even if the text contained is taller than the field, like the font selector shown below:
I've tried using the 'setPrefSize' and 'setMaxSize' textfield methods to force a maximum height.
public static final String display(String savedFamily, String savedStyle, String savedSize, String stylesheet) {
fontFamily = savedFamily;
fontSize = savedSize.substring(0, savedSize.length() - 2);
fontWeight = getChosenWeight(savedStyle);
fontStyle = getChosenStyle(savedStyle);
// Add stage
Stage window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
TextField sample = new TextField("AaBbYyZz");
sample.setEditable(false);
sample.getStyleClass().add("sample");
sample.setAlignment(Pos.CENTER);
sample.setStyle(getCSS());
sample.setPrefSize(200, 60);
sample.setMaxHeight(60);
// Add list view title labels
Label fontLabel = new Label("Font:");
Label fontStyleLabel = new Label("Font Style:");
Label fontSizeLabel = new Label("Font Size: ");
// Add font list view
ListView<String> fontView = new ListView<>();
String fonts[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
for (int i = 0; i < fonts.length; i++) {
fontView.getItems().add(fonts[i]);
}
fontView.getSelectionModel().select(fontFamily);
fontView.setMaxSize(200, 150);
fontView.getSelectionModel().selectedItemProperty().addListener((v) -> {
fontFamily = fontView.getSelectionModel().getSelectedItem();
sample.setStyle(getCSS());
});
// Add font style list view
ListView<String> fontStyleView = new ListView<>();
fontStyleView.getItems().addAll("Regular", "Italic", "Bold", "Bold Italic");
fontStyleView.getSelectionModel().select(savedStyle);
fontStyleView.setMaxSize(80, 150);
fontStyleView.getSelectionModel().selectedItemProperty().addListener((v) -> {
fontStyle = getChosenStyle(fontStyleView.getSelectionModel().getSelectedItem());
fontWeight = getChosenWeight(fontStyleView.getSelectionModel().getSelectedItem());
sample.setStyle(getCSS());
});
// Add font size list view
ListView<String> fontSizeView = new ListView<>();
fontSizeView.getItems().addAll("6", "7", "8", "9", "10", "11", "12", "14", "16", "18", "20", "22", "24", "26", "28");
fontSizeView.getSelectionModel().select(fontSize);
fontSizeView.setMaxSize(80, 150);
fontSizeView.getSelectionModel().selectedItemProperty().addListener((v) -> {
fontSize = fontSizeView.getSelectionModel().getSelectedItem();
sample.setStyle(getCSS());
});
// Add OK button
Button okButton = new Button("OK");
okButton.setOnAction(e -> {
fontCssString = getCSS();
window.close();
});
// Add cancel button
Button cancelButton = new Button("Cancel");
cancelButton.setOnAction(e -> {
window.close();
});
// Add and configure grid pane
GridPane layout = new GridPane();
layout.setPadding(new Insets(15, 15, 15, 15));
layout.setVgap(20);
layout.setHgap(20);
// Set grid constraints for font list view and title
GridPane.setConstraints(fontLabel, 0, 0);
GridPane.setConstraints(fontView, 0, 1);
// Set grid constraints for font style list view and title
GridPane.setConstraints(fontStyleLabel, 1, 0);
GridPane.setConstraints(fontStyleView, 1, 1);
GridPane.setValignment(fontStyleView, VPos.TOP);
// Set grid constraints for font size list view and title
GridPane.setConstraints(fontSizeLabel, 2, 0);
GridPane.setConstraints(fontSizeView, 2, 1);
// Set grid constraints for sample title
GridPane.setConstraints(sample, 0, 2);
GridPane.setHalignment(sample, HPos.CENTER);
// set grid constraints and alignments for buttons
GridPane.setConstraints(okButton, 1, 2);
GridPane.setHalignment(okButton, HPos.RIGHT);
GridPane.setConstraints(cancelButton, 2, 2);
// Add items to grid pane layout
layout.getChildren().addAll(fontLabel, fontView, fontStyleLabel, fontStyleView, fontSizeLabel, fontSizeView,
sample, okButton, cancelButton);
// configure the scene and stage
Scene scene = new Scene(layout, 450, 300);
scene.getStylesheets().add(FontWindow.class.getResource(stylesheet).toExternalForm());
window.setScene(scene);
window.setTitle("Font Options");
window.showAndWait();
return fontCssString;
}
public static final String getChosenStyle(String s) {
String result = "normal";
if (s.contains("Italic")) {
result = "italic";
}
return result;
}
public static final String getChosenWeight(String s) {
String result = "normal";
if (s.contains("Bold")) {
result = "bold";
}
return result;
}
public static String getCSS() {
return "-fx-font-family: " + fontFamily + "; -fx-font-weight: " + fontWeight + "; -fx-font-style: " + fontStyle
+ "; -fx-font-size: " + Float.valueOf(fontSize) / 9.7 + "em;";
}
}
Edit: This has been solved! I was able to get the text field to function as I wanted by setting the maximum and minimum size as well as setting the preferred height and width to 'region.USE_COMPUTED_SIZE'.
This woks to me.
<TextField layoutX="151.0" layoutY="53.0" maxHeight="50.0" maxWidth="255.0" minHeight="50.0" minWidth="255.0" text="AaZz">
...and Pref Height/Pref Width are "USE_COMPUTED_SIZE"
All TextField has preferred padding in each side.
Tips: to change the TextField into the least size, make it sure change also the padding of the TextField to make the size you want.
in JavaFx:
TextField textDisplay = new TextField();
textDisplay.setPrefSize(100,5);
textDisplay.setPadding(new Insets(1,1,1,1));
if you want set the size of your textField base on the fontSize in textField ,just leave it a null "DONT USE" .setPrefSize(double,double); that will set the static size of your textField BUT set the max of your textfield using css/javafx
textDisplay.setMaxWidth(double);
textDisplay.setMaxHeiht(double);
or
textDisplay.setSize(double,double);
but if you use CSS much more easy to design your GUI just dont forget set an ID of your nodes.
textDisplay.setStyle("-fx-pref-width: 100"
+"\n-fx-pref-height: 100"
+"-fx-padding: 5 5 5 5;");
or
textDisplay.setId("idTextDisplay");
#idTextDisplay{
-fx-pref-width: 100;
-fx-pref-height: 100;
-fx-padding: 5 5 5 5;
}
in your case is:
TextField sample = new TextField("AaBbYyZz");
sample.setEditable(false);
sample.getStyleClass().add("sample");
sample.setAlignment(Pos.CENTER);
sample.setStyle(getCSS());
sample.setPrefSize(200, 60);
sample.prefHeight(Region.USE_COMPUTED_SIZE);
sample.prefwidth(Region.USE_COMPUTED_SIZE);
I am currently making a tip calculator and I have hit a wall. My textbook, Big Java, Late Objects, did not have the answer. I scoured stack overflow and a bit of Reddit too but I was only able to partially solve my dilemma. I feel as though I am on the right track. The issue lies within the lambda expression calcTipClick connected to the calculateTipButton. EDIT How can I use the user input from the slider, split check, and checkAmtTextField to do my calculations of the GUI. Sorry
public class TipCalcApp extends Application {
// declare interface controls
Label titleLabel, checkAmtLabel, tipPercentLabel, splitLabel, tipAmtLabel;
Label totalLabel, amtPerPersonLabel;
TextField checkAmtText, tipAmtText, totalText, amtPerPersonText;
Slider tipPercentSlider;
ChoiceBox splitChoiceBox;
Button calcTipButton;
// declare a grid pane (8 rows and 2 columns)
GridPane grid;
#Override
public void start(Stage primaryStage) {
// instantiate labels and their properties
titleLabel = new Label("Tip Calculator");
titleLabel.setMaxWidth(Double.MAX_VALUE);
titleLabel.setAlignment(Pos.CENTER);
checkAmtLabel = new Label("Check Amount");
checkAmtLabel.setMaxWidth(Double.MAX_VALUE);
checkAmtLabel.setAlignment(Pos.CENTER_RIGHT);
tipPercentLabel = new Label("Tip Percent: ");
tipPercentLabel.setMaxWidth(Double.MAX_VALUE);
tipPercentLabel.setAlignment(Pos.CENTER_RIGHT);
splitLabel = new Label("Split");
splitLabel.setMaxWidth(Double.MAX_VALUE);
splitLabel.setAlignment(Pos.CENTER_RIGHT);
tipAmtLabel = new Label("Tip Amount");
tipAmtLabel.setMaxWidth(Double.MAX_VALUE);
tipAmtLabel.setAlignment(Pos.CENTER_RIGHT);
totalLabel = new Label("Total");
totalLabel.setMaxWidth(Double.MAX_VALUE);
totalLabel.setAlignment(Pos.CENTER_RIGHT);
amtPerPersonLabel = new Label("Amount Per Person");
amtPerPersonLabel.setMaxWidth(Double.MAX_VALUE);
amtPerPersonLabel.setAlignment(Pos.CENTER_RIGHT);
// instantiate text fileds and their properties
checkAmtText = new TextField();
tipAmtText = new TextField();
tipAmtText.setEditable(false);
totalText = new TextField();
totalText.setEditable(false);
amtPerPersonText = new TextField();
amtPerPersonText.setEditable(false);
// instantiate a slider and its properties
tipPercentSlider = new Slider();
tipPercentSlider.setPrefWidth(300);
tipPercentSlider.setMin(0);
tipPercentSlider.setMax(25);
tipPercentSlider.setMajorTickUnit(5);
tipPercentSlider.setMinorTickCount(0);
tipPercentSlider.setBlockIncrement(5);
tipPercentSlider.setShowTickLabels(true);
tipPercentSlider.setShowTickMarks(true);
tipPercentSlider.setSnapToTicks(true);
tipPercentSlider.setOrientation(Orientation.HORIZONTAL);
tipPercentSlider.valueProperty().addListener(
(observable, oldvalue, newvalue) ->
{
// show integer values only
tipPercentLabel.setText(String.format("Tip Percent: %2d%s", newvalue.intValue(), "%"));
});
// instantiate a choice box and its properties
splitChoiceBox = new ChoiceBox();
splitChoiceBox.getItems().addAll("1", "2", "3", "4", "5");
splitChoiceBox.setValue("1");
// instantiate a button and its properties
calcTipButton = new Button("Calculate Tip");
calcTipButton.setMaxWidth(Double.MAX_VALUE);
calcTipButton.setOnAction(e -> calcTipClick());
// instantiate a grid pane and its properties
grid = new GridPane();
grid.setHgap(15);
grid.setVgap(15);
grid.setPadding(new Insets(10));
grid.add(titleLabel, 0, 0, 2, 1);
grid.addRow(1, checkAmtLabel, checkAmtText);
grid.addRow(2, tipPercentLabel, tipPercentSlider);
grid.addRow(3, splitLabel, splitChoiceBox);
grid.add(calcTipButton, 0, 4, 2, 1);
grid.addRow(5, tipAmtLabel, tipAmtText);
grid.addRow(6, totalLabel, totalText);
grid.addRow(7, amtPerPersonLabel, amtPerPersonText);
// instantiate the grid pane and put items in in grid
Scene scene = new Scene(grid);
scene.getRoot().setStyle("-fx-font: 15 'Comic Sans MS'");
primaryStage.setTitle("Tip Calculator");
primaryStage.setScene(scene);
primaryStage.show();
}
private void calcTipClick() {
//Gather choiceBox
String choiceInput = splitChoiceBox.getValue().toString();
int choiceSelection = Integer.parseInt(choiceInput.substring(0, 1));
//Gather Slider information
String sliderInput;
sliderInput = tipPercentLabel.getValue().toString();
int sliderSelection = Integer.parseInt(sliderInput.substring(0, 1));
//Gather textField amount
}
Not sure if this is what you are asking, but this is an idea of how you can calculate the tip and split it in your calcTipClick() method. You should look at formatters to ensure format, rounding, etc. But this should give you the general idea.
private void calcTipClick() {
//Gather choiceBox
String choiceInput = splitChoiceBox.getValue().toString();
int choiceSelection = Integer.parseInt(choiceInput.substring(0, 1));
//Gather Slider information
Number sliderInput = tipPercentSlider.getValue();
//Gather textField amount
String val = checkAmtText.getText();
NumberStringConverter nsc = new NumberStringConverter();
Number amount = 0;
try {
amount = nsc.fromString(val);
}catch (Exception pe) {
//Need to handle a parse error if the user isn't entering numbers
//Should look at text formatters to ensure amount is only entered valid
amount = 0;
}
Number tipAmount = amount.doubleValue() * sliderInput.doubleValue()/100;
tipAmtText.setText(tipAmount.toString());
Number totalAmount = tipAmount.doubleValue() + amount.doubleValue();
totalText.setText(totalAmount.toString());
Number perPerson = totalAmount.doubleValue() / choiceSelection;
amtPerPersonText.setText(perPerson.toString());
}
I have the following code which is a grouping of buttons in javafx:
ToggleGroup groupLevelQ = new ToggleGroup();
class MyLevelButton extends ToggleButton {
public MyLevelButton(String name) {
super(name);
setPrefWidth(50.0);
setPrefHeight(50.0);
setStyle("-fx-font: 20 cornerstone; -fx-base: #17499F;");
setToggleGroup(groupLevelQ);
}
}
oneLevelButton = new MyLevelButton("1");
twoLevelButton = new MyLevelButton("2");
threeLevelButton = new MyLevelButton("3");
fourLevelButton = new MyLevelButton("4");
fiveLevelButton = new MyLevelButton("5");
sixLevelButton = new MyLevelButton("6");
sevenLevelButton = new MyLevelButton("7");
eightLevelButton = new MyLevelButton("8");
nineLevelButton = new MyLevelButton("9");
oneLevelButton.setUserData("1");
twoLevelButton.setUserData("2");
threeLevelButton.setUserData("3");
fourLevelButton.setUserData("4");
fiveLevelButton.setUserData("5");
sixLevelButton.setUserData("6");
sevenLevelButton.setUserData("7");
eightLevelButton.setUserData("8");
nineLevelButton.setUserData("9");
groupLevelQ.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
public void changed(ObservableValue<? extends Toggle> ov, Toggle toggle, Toggle new_toggle) {
if (new_toggle != null) {
textLevelQ = (String) groupLevelQ.getSelectedToggle().getUserData();
}
}
});
addQButtonPane.add(oneLevelButton, 1, 9);
addQButtonPane.add(twoLevelButton, 2, 9);
addQButtonPane.add(threeLevelButton, 3, 9);
addQButtonPane.add(fourLevelButton, 4, 9);
addQButtonPane.add(fiveLevelButton, 5, 9);
addQButtonPane.add(sixLevelButton, 6, 9);
addQButtonPane.add(sevenLevelButton, 7, 9);
addQButtonPane.add(eightLevelButton, 8, 9);
addQButtonPane.add(nineLevelButton, 9, 9);
In fact I am creating buttons and I add them in a GridPane. I am trying to figure out how can I define the distance between the buttons. Basically as they are right now they have a default distance them and I want to change that.
EDIT:
addQButtonPane = new GridPane();
addQButtonPane.setHgap(10);
addQButtonPane.setVgap(10);
addQButtonPane.setPadding(new Insets(0, 50, 0, 50));
addQButtonPane.setStyle("-fx-background-color: #95CBE5;");
This is the way that my gridpane is formatted. But still I want to change this formation just for the specific mentioned buttons.
EDIT2:
Maybe the kind of layout you're trying to achieve could be better achieved by placing HBoxes containing the options and Text elements inside a VBox.
But if you're looking for a way to "take the buttons out of the usual layout", you could simply place them inside a HBox use a columnSpan that covers all remaining columns:
double buttonDistance = ...
int gridPaneColumnCount = ...
HBox buttonBox = new HBox(buttonDistance,
oneLevelButton,
twoLevelButton,
threeLevelButton,
fourLevelButton,
fiveLevelButton,
sixLevelButton,
sevenLevelButton,
eightLevelButton,
nineLevelButton);
addQButtonPane.add(buttonBox, 1, 9, gridPaneColumnCount-1, 1);
I want to put 3 fixed size group in the composite in A side. And I want to place the image and the label middle of this group. My example image and code is below. The problem is the groups are resize according to label size in them and labels were written top of the group, but I want the place groups as equal fixed size to cover width of A side and labels should be vertically middle of the group.
private void designComposite() {
Section sectionA = toolkit.createSection(form.getBody(), Section.TITLE_BAR);
sectionA.setText("A");
Composite sectionClientA = toolkit.createComposite(sectionA);
sectionClientA.setLayout(new RowLayout());
Composite dynamicDataComp = toolkit.createComposite(sectionClientA);
dynamicDataComp.setLayout(new RowLayout());
Group group_incom = new Group(dynamicDataComp, SWT.NONE);
group_incom.setLayout(new RowLayout());
Label lbl_img_incom = new Label(group_incom, SWT.CENTER);
Image img_incom = new Image(lbl_img_incom.getDisplay(),
"<path>");
lbl_img_incom.setImage(img_incom);
group_incom.setText("# of Incoming Messages :");
Label lbl_incomMsg = toolkit.createLabel(group_incom, "99", SWT.CENTER | SWT.VERTICAL);
Font incomFont = new Font(lbl_incomMsg.getDisplay(), new FontData("Arial", 12, SWT.BOLD));
lbl_incomMsg.setFont(incomFont);
lbl_incomMsg.pack();
Group group_outgo = new Group(dynamicDataComp, SWT.NONE);
group_outgo.setLayout(new RowLayout());
Label lbl_img_outgo = new Label(group_outgo, SWT.CENTER);
Image img_outgo = new Image(lbl_img_outgo.getDisplay(),
"<path>");
lbl_img_outgo.setImage(img_outgo);
group_outgo.setText("# of Outgoing Messages :");
Label lbl_outgoMsg = toolkit.createLabel(group_outgo, "145639612", SWT.CENTER);
Font outgoFont = new Font(lbl_outgoMsg.getDisplay(), new FontData("Arial", 13, SWT.BOLD));
lbl_outgoMsg.setFont(outgoFont);
lbl_outgoMsg.pack();
Group group_error = new Group(dynamicDataComp, SWT.NONE);
group_error.setLayout(new RowLayout());
Label lbl_img_error = new Label(group_error, SWT.CENTER);
Image img_error = new Image(lbl_img_error.getDisplay(),
"<path>");
lbl_img_error.setImage(img_error);
group_error.setText("# of Error Messages :");
Label lbl_errorMsg = toolkit.createLabel(group_error, "345", SWT.CENTER);
Font errorFont = new Font(lbl_errorMsg.getDisplay(), new FontData("Arial", 13, SWT.BOLD));
lbl_errorMsg.setFont(errorFont);
lbl_errorMsg.pack();
sectionA.setClient(sectionClientA);
}
Use the GridLayout and set the columns equal width:
Composite dynamicDataComp = new Composite(parent, SWT.NONE);
dynamicDataComp.setLayout(new GridLayout(3, true));
dynamicDataComp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
Group group_incom = new Group(dynamicDataComp, SWT.NONE);
group_incom.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
group_incom.setLayout(new RowLayout());
//...
One way is to use GridLayout for the parent composite and tell it use 3 equal sized columns:
Composite dynamicDataComp = toolkit.createComposite(sectionClientA);
dynamicDataComp.setLayout(new GridLayout(3, true));
I have a JPanel and for example, if I click on the button "INSERT", I can add a JButton and a JLabel. My problem is I need to insert the JLabel under the JButton. The JLabel text must centred respect the JButton text. After that, I want a space around 10 pixels to use again my "INSERT" button and add horizontally a new pair on JButton and JLabel with the same orientation.
Thanks!
PD: Please, complement your question with an attempt.
Here is a quick example that shows a dynamic (which is what I assume you wanted) setup to allow insertion of an undefined number of panels:
public class AwesomeAnswer {
public static void main(String[] args) {
// please not that this is only an example and not a
// Swing thread safe way of starting a JFrame
JFrame frame = new JFrame();
JPanel content = (JPanel)frame.getContentPane();
// create our top panel that will hold all of the inserted panels
JPanel page = new JPanel();
page.setLayout( new BoxLayout( page, BoxLayout.Y_AXIS ) );
// add our page to the frame content pane
content.add( page );
// add two button/label panels
page.add( insert( "This is an awesome answer", "Accept" ) );
page.add( insert( "Say thank you", "Thank" ) );
frame.pack();
frame.setVisible( true );
}
public static final JPanel insert( String labelText, String buttonText ) {
// create the label and the button
JLabel lbl = new JLabel( labelText );
JButton btn = new JButton( buttonText );
// create the panel that will hold the label and the button
JPanel wrapPanel = new JPanel( new GridBagLayout() );
wrapPanel.setBorder( BorderFactory.createEmptyBorder( 10, 10, 10, 10 ) );
// tell the grid bag how to behave
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 0;
gbc.gridheight = 2;
// make the button centered
JPanel buttonPanel = new JPanel( new FlowLayout( 0, 0, FlowLayout.CENTER ) );
buttonPanel.add( btn );
// make the label centered
JPanel labelPanel = new JPanel( new FlowLayout( 0, 0, FlowLayout.CENTER ) );
labelPanel.add( lbl );
// add our button and label to the grid bag with our constraints
wrapPanel.add( buttonPanel, gbc );
wrapPanel.add( labelPanel, gbc );
return wrapPanel;
}
}
I think that you have something like that
rootPane
+-----panelButton
| +------JButton
|
+-----panelPanels
+-----panel
+---JButton
+---JLabel
The SpringLayout can help you
SpringUtilities.makeGrid(panel,
2, 1, //rows, cols
0, 0, //initialX, initialY
5, 5);//xPad, yPad