I'm trying to make a box that allows you to select some variables, and re-order the ones that are selected. So the LEFT box starts filled, the RIGHT box starts empty. You move items from the left to the right, and on the right you can re-arrange their order (with the up and down buttons). This lets you pick what items you want and in what order (for sorting purposes in another section of the program).
The layout I'm going for looks like of like this:
Unfortunately, it's coming out like... well... :-(
The functionality I'm looking for all works. Yay. I am just having a very hard time with the layout. I think if I can reach the following four primary objectives, I'll be set.
How can I get the OK and CANCEL buttons on the bottom instead of above the multis?
How can I get the multis to have a pre-set size (let's say... 10)
How can I get the arrow buttons to be stacked vertically instead of horizontally?
How can I get the arrow buttons to be between the two multis?
I figure each of these particular objectives are probably one-liners, perhaps a little bit of plumbing here and there...
On a side note, I'm using GridLayout - this might be a poor choice. Is there a better choice for something like this?
Without further ado, here's the code that generates this horrid mess...
#Override
protected Control createDialogArea(Composite parent) {
parent.getShell().setText("Multi-sort");
Composite dialogcomp = new Composite(parent, SWT.NONE);
dialogcomp.setLayout(new GridLayout(3, false));
available = new List(getShell(), SWT.BORDER | SWT.V_SCROLL);
for(String t : MultiSortDialog.availableNames) {
available.add(t);
}
used = new List(getShell(), SWT.BORDER | SWT.V_SCROLL);
for(String t : MultiSortDialog.usedNames) {
used.add(t);
}
createButton(parent, ADD, ">", false);
createButton(parent, REM, "<", false);
createButton(parent, UP, "^", false);
createButton(parent, DOWN, "V", false);
return dialogcomp;
}
I would suggest you simple use the Dialog's default OK and Cancel buttons and not trying to lay out your own. SWT has a nice system for placing them in the system default location (i.e., on Mac OS, the OK button will be on the right, which is the correct location.)
Don't use Dialog.createButton() to create buttons. This creates a button on your dialog which, although it sounds like what you want to do, actually isn't. This creates a button in the style of OK or Cancel buttons, expected to be placed in the button bar composite that the Dialog class owns and styled appropriately for the bottom row OK/Cancel buttons. You want to create a new Button in the composite you're creating. That is:
Button addButton = new Button(dialogcomp, SWT.PUSH);
addButton.setText(">");
addButton.addSelectionListener(...);
To stack the buttons vertically, create a new composite inside dialogcomp to contain them.
To put the arrow buttons between the Lists, you need to ensure that you add things in the correct order. With a GridLayout, you need to add widgets in the order that you want them to appear.
Other points:
Don't change the title of the dialog by calling Shell.setText(). Call setText() in your
Don't try to parent your Lists inside the parent shell. You're given a composite to put things in. This will wreak havoc on your layouts. You're basically hoisting widgets up into things you don't own and don't layout. Instead, put it in the Composite you created.
You may also wish to create buttons with the type SWT.ARROW | SWT.LEFT instead of simply drawing a < sign. It may be more visually appealing. Just something to investigate.
A simple rearrangement of your code, creating Buttons properly, and creating a new composite to hold the buttons, will get you much closer:
Composite dialogcomp = new Composite(parent, SWT.NONE);
dialogcomp.setLayout(new GridLayout(3, false));
available = new List(dialogcomp, SWT.BORDER | SWT.V_SCROLL);
for(String t : MultiSortDialog.availableNames) {
available.add(t);
}
Composite buttonComposite = new Composite(dialogcomp, SWT.NONE);
buttonComposite.setLayout(new GridLayout(1, false));
Button addButton = new Button(buttonComposite, SWT.PUSH);
addButton.setText(">");
Button removeButton = new Button(buttonComposite, SWT.PUSH);
removeButton.setText("<");
Button upButton = new Button(buttonComposite, SWT.PUSH);
upButton.setText("^");
Button downButton = new Button(buttonComposite, SWT.PUSH);
downButton.setText("v");
used = new List(dialogcomp, SWT.BORDER | SWT.V_SCROLL);
for(String t : MultiSortDialog.usedNames) {
used.add(t);
}
This will probably get you pretty close to what you want. However, you will probably want to apply GridDatas for each of your instances. For example, your two Lists will probably want to grab and fill horizontally and vertically to fill the layout as the Dialog is resized. But I'll leave that as an exercise for the reader.
Related
I'm writing a small program in which multiple shapes will be visible in JavaFX. I'm trying to create a button through which it is possible to change all the shape's color to the chosen one by the user.
Right now, I'm only able to do that by changing each shape individually in my lambda expression. It's okay for now since there's only three shapes, but it will be inconvenient further one. Can anyone think of a way to group all the shapes together and access the "setFill" method to change them all at once?
Here's the code:
// Calling Semi-Circle method
Arc semicircle1 = shapes1.getsemicircle();
// create Colors button and set is as invisible until a shape value is passed by user
Button buttonColors = new Button();
buttonColors.setText("Choose a color for the Shape");
buttonColors.setVisible(true);
buttonColors.setOnAction( e ->
{
if (textField1.getText().equalsIgnoreCase("Grey"))
{
label1.setText("Grey");
semicircle1.setFill(Color.GREY);
}
});
You may create some property and bind all shapes to it
final ObjectProperty<Paint> fillProperty = new SimpleObjectProperty(Color.GREY);
...
semicirle1.fillProperty().bind(fillProperty);
pentagon1.fillProperty().bind(fillProperty);
rectangle1.fillProperty().bind(fillProperty);
...
fillProperty.set(Color.RED);
I want to create checkbox with text in the left side and the checkbox component on the right side. How I can switch their place?
CheckBox cb = new CheckBox("Show on Startup");
In JavaFX 8, you can do it like this:
Label lb = new Label("left check");
lb.setGraphic(new CheckBox());
lb.setContentDisplay(ContentDisplay.RIGHT); //You can choose RIGHT,LEFT,TOP,BOTTOM
There might be an easier way, but you can use a label and wrap it with the CheckBox in a HBox:
HBox box = new HBox();
CheckBox cb = new CheckBox();
Label text = new Label("Show on Startup");
box.getChildren().addAll(text, cb);
box.setSpacing(5);
It would be nice if the CheckBox considered the box as its "content" like some of the other controls based on Labeled. Then the contentDisplayProperty could be set to ContentDisplay.RIGHT to achieve this. A nice side-effect would be that we could change the rendering of the box with a setGraphic() call.
As of my release (1.8 EA b129), CheckBox doesn't work that way.
First of all, I'm a long time Java/Swing developer. I recently installed JavaFX 2.2 to play around with.
I'm creating a fairly simple app, whose main window has a toolbar on top and content in the rest of the window. The obvious way to accomplish this is to use a BorderPane, and stick a ToolBar into the top section. So far, so good. However, I would like some of the controls in the toolbar to be at the left edge of the window, and some at the right edge. I can find no way to do this. I can put an invisible spacer object into the toolbar, but I only know how to give it a fixed width; it doesn't resize when the window is resized.
So I thought that instead of using a ToolBar object, I'll just use an HBox; it should be equivalent to a horizontally-oriented Swing Box object, right? And the Swing Box class has a createHorizontalGlue() method that inserts an auto-sizing spacer. Well, I can't find an equivalent in the JavaFX HBox class. Is there no simple way to do this?
I figured out how to do it using an HBox instead of a ToolBar to hold the controls; the key is the HBox.setHgrow() method, which allows you to set a spacer object to grow to fill the available space. I still don't know if it's possible to do this with an actual ToolBar instance.
/**
* Creates and populates the Node that serves as the window toolbar.
*
* #return a newly constructed and populated toolbar component
*/
private Node makeToolbar() {
// Auto-sizing spacer
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
// Horizontal box containing toolbar controls
HBox box = new HBox();
box.setPadding(new Insets(8));
box.setAlignment(Pos.CENTER);
box.getChildren().addAll(openButton, spacer, resizeSlider);
// Colored background panel with drop shadow
Pane bgRect = new Pane();
bgRect.setStyle("-fx-background-color: #e0e0e0;");
bgRect.setEffect(DropShadowBuilder.create().width(1).build());
// StackPane to hold box and rectangle
StackPane stack = new StackPane();
stack.getChildren().addAll(bgRect, box);
return stack;
}
i do it this way:
private Node makeFooter(Node left, Node right) {
ToolBar footer = new ToolBar();
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
spacer.setMinWidth(Region.USE_PREF_SIZE);
footer.getItems().addAll(left, spacer, right);
return footer;
}
hope i could help someone
how to put 4 button in row, as in the picture:
The distance between the elements should be changed at different resolutions
There are allot of ways to do everything in LWUIT. Its unclear from your image what your exact constraints are, I'm guessing you want the left most button to be left aligned and the right most to be right aligned. You probably also want the two other buttons to be centered.
I would implement this using a GridLayout with nested FlowLayout elements. As such:
Container c = new Container(new GridLayout(1, 4));
addButton(c, new Button("b1"), Component.LEFT);
addButton(c, new Button("b2"), Component.CENTER);
addButton(c, new Button("b3"), Component.CENTER);
addButton(c, new Button("b4"), Component.RIGHT);
private void addButton(Container c, Button b, int align) {
Container flow = new Container(new FlowLayout(align));
flow.addComponent(b);
c.addComponent(flow);
}
Play with setMargin(Component.RIGHT,x) for the first three Buttons. Set the value of x such that the Buttons are equi-partitioned in the row : you must take into account the preferredWidth of the Buttons for that. For the first Button set its margin-left to 0 ( setMargin(Component.LEFT,0) ) , and for the last Button set its right-margin to 0 ( setMargin(Component.RIGHT,0) ).
You should use use BorderLayout and add the container (described in this answer inside south)
I was wondering if it was possible to replace one control in a TableLayoutPanel with another at runtime. I have a combo box and a button which are dynamically added to the TableLayoutPanel at runtime, and when the user selects an item in the combo box and hits the button, I'd like to replace the combobox with a label containing the text of the selected combo box item.
Basically, if I could simply remove the control and insert another at it's index, that would work for me. However I don't see an option like "splice" or "insert" on the Controls collection of the TableLayoutPanel, and I was wondering if there was a simple way to insert a control at a specific index. Thanks in advance.
Fixed this by populating a panel with the two controls I wanted to swap and putting that into the TableLayoutPanel. Then I set their visibility according to which I wanted to see at what time.
This is what I've been able to come up with for what I needed. It gets the position of the ComboBox and makes a new label using the selected value.
// Replaces a drop down menu with a label of the same value
private void lockDropMenu(ComboBox dropControl)
{
TableLayoutPanelCellPosition pos = myTable.GetCellPosition(dropControl);
Label lblValue = new Label();
myTable.Controls.Remove(dropControl);
if (dropControl.SelectedItem != null)
{
lblValue.Text = dropControl.SelectedItem.ToString();
lblValue.Font = lblValue.Font = dropControl.Font;
// Just my preferred formatting
lblValue.AutoSize = true;
lblValue.Dock = System.Windows.Forms.DockStyle.Fill;
lblValue.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
myTable.Controls.Add(lblValue, pos.Column, pos.Row);
}
}