I added into my table the option table.setTableMenuButtonVisible(true); in order to show and hide columns.
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class MainApp extends Application
{
private TableView table = new TableView();
public static void main(String[] args)
{
launch(args);
}
#Override
public void start(Stage stage)
{
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(300);
stage.setHeight(500);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
TableColumn firstNameCol = new TableColumn("First Name");
TableColumn lastNameCol = new TableColumn("Last Name");
TableColumn emailCol = new TableColumn("Email");
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
table.setTableMenuButtonVisible(true);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
}
Can I for example show the columns First Name and Last Name by default and to hide Email?
Is there any option for this?
Related
I've noticed that if I set the font of an object using setFont(), it always renders on the screen quite a bit smaller than if I set that same font using setStyle(). Why is this?
For Example:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.FlowPane;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
FlowPane contentPane = new FlowPane();
contentPane.setPadding(new Insets(10));
Text setFontText = new Text("setFont(\"Courier\", 14)");
setFontText.setFont(Font.font("Courier", 14));
Text setStyleText = new Text("setStyle(\"-fx-font-family:Courier; -fx-font-size: 14pt\")");
setStyleText.setStyle("-fx-font-family: Courier; -fx-font-size: 14pt");
contentPane.getChildren().addAll(setFontText, setStyleText);
primaryStage.setTitle("These Fonts Though");
primaryStage.setScene(new Scene(contentPane, 500, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
This produces the following display:
The circle should go back and forth but the start button is not starting it for some reason? When I ran the example file it worked and it looks exactly like mine so not sure why Mine isnt starting. Does anybody know why? Thanks
package projavafx.metronometransition.ui;
import javafx.animation.Animation;
import javafx.animation.Interpolator;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class MetronomeTransitionMain extends Application{
Button startButton;
Button pauseButton;
Button resumeButton;
Button stopButton;
Circle circle;
public static void main(String[] args) { Application.launch(args);}
#Override
public void start(Stage stage) {
circle = new Circle(100, 50, 4, Color.BLUE);
TranslateTransition anim = new TranslateTransition(new Duration(1000.0), circle);
anim.setFromX(0);
anim.setToX(200);
anim.setAutoReverse(true);
anim.setCycleCount(Animation.INDEFINITE);
anim.setInterpolator(Interpolator.LINEAR);
startButton = new Button("start");
startButton.setOnAction(e -> anim.playFromStart());
pauseButton = new Button("pause");
startButton.setOnAction(e -> anim.pause());
resumeButton = new Button("resume");
resumeButton.setOnAction(e -> anim.play());
stopButton = new Button("stop");
stopButton.setOnAction(e -> anim.stop());
HBox commands = new HBox(10, startButton,
pauseButton,
resumeButton,
stopButton);
commands.setLayoutX(60);
commands.setLayoutY(420);
Group group = new Group(circle, commands);
Scene scene = new Scene(group, 400, 500);
startButton.disableProperty().bind(anim.statusProperty()
.isNotEqualTo(Animation.Status.STOPPED));
pauseButton.disableProperty().bind(anim.statusProperty()
.isNotEqualTo(Animation.Status.RUNNING));
resumeButton.disableProperty().bind(anim.statusProperty()
.isNotEqualTo(Animation.Status.PAUSED));
stopButton.disableProperty().bind(anim.statusProperty()
.isEqualTo(Animation.Status.STOPPED));
stage.setScene(scene);
stage.setTitle("Metronome using TranslateTransition");
stage.show();
}
}
I just want to create copiable label in JavaFX.
I have tried to create TextField that have no background, have no focus border and default background color, but I have no success.
I have found a lot of questions how to remove focus background from control but all of that looks like "hacks".
Is there are any standard solution to implement copyable text?
You can create a TextField without the border and background color with css:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class CopyableLabel extends Application {
#Override
public void start(Stage primaryStage) {
TextField copyable = new TextField("Copy this");
copyable.setEditable(false);
copyable.getStyleClass().add("copyable-label");
TextField tf2 = new TextField();
VBox root = new VBox();
root.getChildren().addAll(copyable, tf2);
Scene scene = new Scene(root, 250, 150);
scene.getStylesheets().add(getClass().getResource("copyable-text.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
and
copyable-text.css:
.copyable-label, .copyable-label:focused {
-fx-background-color: transparent ;
-fx-background-insets: 0px ;
}
This is the solution I used, where there is a small button besides the label to be able to copy the text:
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import org.controlsfx.glyphfont.FontAwesome;
import org.controlsfx.glyphfont.Glyph;
import java.util.Locale;
public class CopiableLabel extends Label
{
public CopiableLabel()
{
addCopyButton();
}
public CopiableLabel(String text)
{
super(text);
addCopyButton();
}
public CopiableLabel(String text, Node graphic)
{
super(text, graphic);
}
private void addCopyButton()
{
Button button = new Button();
button.visibleProperty().bind(textProperty().isEmpty().not());
button.managedProperty().bind(textProperty().isEmpty().not());
button.setFocusTraversable(false);
button.setPadding(new Insets(0.0, 4.0, 0.0, 4.0));
button.setOnAction(actionEvent -> AppUtils.copyToClipboard(getText()));
Glyph clipboardIcon = AppUtils.createFontAwesomeIcon(FontAwesome.Glyph.CLIPBOARD);
clipboardIcon.setFontSize(8.0);
button.setGraphic(clipboardIcon);
setGraphic(button);
setContentDisplay(ContentDisplay.RIGHT);
}
}
In my JavaFX application I have a ImageView on the stage. I wanted to add both effects Glow and Sepia, and both should be gradually increasing (0 to 1) within duration 5 sec.
How do I do this with code?
Both effects should be applied in parallel. Would it make the animation slower?
Use a Timeline with one KeyFrame at the start and one at the end. For each KeyFrame just set the value of each effect:
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO,
new KeyValue(glow.levelProperty(), 0),
new KeyValue(sepia.levelProperty(), 0)),
new KeyFrame(Duration.seconds(5),
new KeyValue(glow.levelProperty(), 1),
new KeyValue(sepia.levelProperty(),1))
);
SSCCE:
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.effect.Glow;
import javafx.scene.effect.SepiaTone;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Duration;
public class AnimatedEffects extends Application {
private static final String IMAGE_URL = "http://www.nasa.gov/sites/default/files/styles/full_width/public/thumbnails/image/nh-charon-neutral-bright-release.jpg?itok=20aE3TAH";
#Override
public void start(Stage primaryStage) {
ImageView image = new ImageView(new Image(IMAGE_URL, 400, 400, true, true));
Glow glow = new Glow(0);
SepiaTone sepia = new SepiaTone(0);
sepia.setInput(glow);
image.setEffect(sepia);
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO,
new KeyValue(glow.levelProperty(), 0),
new KeyValue(sepia.levelProperty(), 0)),
new KeyFrame(Duration.seconds(5),
new KeyValue(glow.levelProperty(), 1),
new KeyValue(sepia.levelProperty(),1))
);
Button effectButton = new Button("Add effect");
effectButton.setOnAction(e -> timeline.play());
BorderPane root = new BorderPane(image, null, null, effectButton, null);
BorderPane.setAlignment(effectButton, Pos.CENTER);
BorderPane.setMargin(effectButton, new Insets(10));
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I have a map mapping symbols to prices.I want to display a table with one column containing keys and the other column containing corresponding values in JavaFX
public class myMap {
Map<Symbol, Price> map;
}
I want to display a table like the following
Symbol | Price
I guess it can be done by using TableView with CallBack.
Since I've already done something similar to this I'll add my code.
import java.util.Map;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableMap;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.converter.NumberStringConverter;
public class MapTable extends Application {
#Override
public void start(Stage primaryStage) {
final ObservableMap<String, Number> obsMap = FXCollections.observableHashMap();
for (int i = 0; i < 3; i++) obsMap.put("key "+i, i*10d);
final TableView<ObservableMap.Entry<String, Number>> tv = new TableView(FXCollections.observableArrayList(obsMap.entrySet()));
tv.setEditable(true);
obsMap.addListener((MapChangeListener.Change<? extends String, ? extends Number> change) -> {
tv.setItems(FXCollections.observableArrayList(obsMap.entrySet()));
});
TableColumn<ObservableMap.Entry<String, Number>,String> keyCol = new TableColumn<>("key");
TableColumn<ObservableMap.Entry<String, Number>,Number> priceCol = new TableColumn<>("price");
tv.getColumns().addAll(keyCol,priceCol);
keyCol.setCellValueFactory((p) -> {
return new SimpleStringProperty(p.getValue().getKey());
});
keyCol.setCellFactory(TextFieldTableCell.forTableColumn());
keyCol.setOnEditCommit((TableColumn.CellEditEvent<Map.Entry<String,Number>, String> t) -> {
final String oldKey = t.getOldValue();
final Number oldPrice = obsMap.get(oldKey);
obsMap.remove(oldKey);
obsMap.put(t.getNewValue(),oldPrice);
});
priceCol.setCellValueFactory((p) -> {
return new ReadOnlyObjectWrapper<>(p.getValue().getValue());
});
priceCol.setCellFactory(TextFieldTableCell.forTableColumn(new NumberStringConverter()));
priceCol.setOnEditCommit((TableColumn.CellEditEvent<Map.Entry<String,Number>, Number> t) -> {
obsMap.put(t.getTableView().getItems().get(t.getTablePosition().getRow()).getKey(),//key
t.getNewValue());//val);
});
Button btn1 = new Button();
btn1.setText("Add data");
btn1.setOnAction((ActionEvent event) -> {
obsMap.put("hi",100);
});
Button btn2 = new Button();
btn2.setText("verify data");
btn2.setOnAction((ActionEvent event) -> {
for (Map.Entry<String,Number> me : obsMap.entrySet())
System.out.println("key "+me.getKey()+" val "+me.getValue());
});
VBox root = new VBox(tv,btn1,btn2);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Map Table test");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Hope this can help.
public class Demo {
public static void main(String[] args) {
// Use Java Collections to create the List.
Map<String,String> map = new HashMap<String,String>();
// Now add observability by wrapping it with ObservableList.
ObservableMap<String,String> observableMap = FXCollections.observableMap(map);
observableMap.addListener(new MapChangeListener() {
#Override
public void onChanged(MapChangeListener.Change change) {
System.out.println("Detected a change! ");
}
});
// Changes to the observableMap WILL be reported.
observableMap.put("key 1","value 1");
System.out.println("Size: "+observableMap.size());
// Changes to the underlying map will NOT be reported.
map.put("key 2","value 2");
System.out.println("Size: "+observableMap.size());
}
}
http://docs.oracle.com/javafx/2/collections/jfxpub-collections.htm