I'm beginner in JavaFX.
I need to make one-at-a-time handler for any changes in the check boxes for my TreeView. Now it works like it handles all selected nodes simultaneously.
Thanks for help. Here is my code:
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.CheckBoxTreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.CheckBoxTreeCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
BorderPane root = new BorderPane();
root.setCenter(initTreeView());
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public TreeView initTreeView() {
TreeView<String> treeView = new TreeView<>();
treeView.setRoot(new CheckBoxTreeItem<>("123"));
treeView.getRoot().addEventHandler(CheckBoxTreeItem.checkBoxSelectionChangedEvent(), event -> System.out.println("hello"));
treeView.setCellFactory(p -> new CheckBoxTreeCell<>());
treeView.getRoot().getChildren().addAll(new CheckBoxTreeItem<>("1"),new CheckBoxTreeItem<>("2"), new CheckBoxTreeItem<>("3"));
treeView.getRoot().getChildren().get(0).getChildren().addAll(new CheckBoxTreeItem<>("4"),new CheckBoxTreeItem<>("5"), new CheckBoxTreeItem<>("6"));
treeView.getRoot().getChildren().get(1).getChildren().addAll(new CheckBoxTreeItem<>("7"),new CheckBoxTreeItem<>("8"), new CheckBoxTreeItem<>("9"));
treeView.getRoot().getChildren().get(2).getChildren().addAll(new CheckBoxTreeItem<>("10"),new CheckBoxTreeItem<>("11"), new CheckBoxTreeItem<>("12"));
return treeView;
}
public static void main(String[] args) {
launch(args);
}
}
Actually it works correctly. Your event handler is called once for every changed checkbox node. Just note that changing subnodes affects parent ones as well, so you get several event handles calls.
Try next code instead which prints the name of the affected checkbox:
treeView.getRoot().addEventHandler(CheckBoxTreeItem.checkBoxSelectionChangedEvent(),
event -> System.out.println("hello " + event.getTreeItem().getValue()));
For example, if you click on checkbox "5" you will get the following log:
hello 5
hello 1
hello 123
because all parent node have changed state as well (from unchecked to intermediate "-" state). If you click "6" after that only one checkbox is affected and output will be:
hello 6
Related
I am trying to use naive map.
I have places a MapContainer insider a Form Component but the From shows blank without the map inside it, on the simulator. When I click on the viewport the map shows as long as the mouse button remains down. When I release it disappear again.
Is it a real problem or is it a misfunction of the simulator? If it is a real problem what am I doing wrong?
below is the class I am using:
package com.mainsys.zappeion;
import com.codename1.googlemaps.MapContainer;
import com.codename1.maps.Coord;
import com.codename1.ui.Form;
import com.codename1.ui.layouts.BorderLayout;
/**
*
* #author Christoforos
*/
public class ZappeionMap extends com.codename1.ui.Form {
private Form current;
public ZappeionMap() {
super("Ζάππειον", new BorderLayout());
}
#Override
public void show() {
if(current != null){
current.show();
return;
}
final MapContainer cnt = new MapContainer();
this.addComponent(BorderLayout.CENTER, cnt);
cnt.setCameraPosition(new Coord(41.889, -87.622));
super.show();
}
}
/********** Implementing Shai's answer ******************/
I changed my code to what Shai suggested show my class now is:
package com.mainsys.zappeion;
import com.codename1.googlemaps.MapContainer;
import com.codename1.location.Location;
import com.codename1.location.LocationManager;
import com.codename1.maps.Coord;
import com.codename1.ui.BrowserComponent;
import com.codename1.ui.FontImage;
import com.codename1.ui.Form;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.plaf.Style;
/**
*
* #author Christoforos
*/
public class ZappeionMap extends com.codename1.ui.Form {
private Form current;
private static final String HTML_API_KEY = "AIzaSyDHlFJK561bQVs0AyBm1M5xWS_YCHNuPfc";
public ZappeionMap() {
super("Ζάππειον", new BorderLayout());
final MapContainer cnt = new MapContainer( HTML_API_KEY );
this.addComponent(BorderLayout.CENTER, cnt);
cnt.setCameraPosition(new Coord(41.889, -87.622));
}
}
It still having the same problem. The screen is blank. The map only shown when I click on the screen.
I also noticed something else. On the debuger I get the message:
WARNING: Apple will no longer accept http URL connections from applications you tried to connect to http://tile.openstreetmap.org/4/2/9.png to learn more check out https://www.codenameone.com/blog/ios-http-urls.html
Why is it trying to connect to http://tile.openstreetmao.org. It is supposed to work with google maps not with openstreet maps.
One more information, maybe it is worh something. I test it on real device. The screen is still blink but when I touch the screen it does not show anythink, in contrast with the simulater that when I click on the screen the map appears.
I am using netbeans 8.2 on centos 7
Any help is appreciated.
Thank you Christoforos.
Why are you overriding the show method of form and don't construct the UI n the constructor?
It looks like you copied some code from the lifecycle class and mixed it with a form subclass e.g. the current variable.
This is closer to correct:
public class ZappeionMap extends com.codename1.ui.Form {
private Form current;
public ZappeionMap() {
super("Ζάππειον", new BorderLayout());
final MapContainer cnt = new MapContainer();
this.addComponent(BorderLayout.CENTER, cnt);
cnt.setCameraPosition(new Coord(41.889, -87.622));
}
}
I created an empty TextField test and an empty TextField test2 in the "start" method
public void start(Stage primaryStage) throws Exception {}
Now I want to check constantly if test.getText().equals(""). If so, test2.setEditable(false), otherwise test2.setEditable(true).
I don't know how to implement it, as it needs to get checked constantly.
I already tried to implement an if-Statement in the start method and it actually set test2 on notEditable at the beginning, astest is empty but when test.getText().equals("") changed to !test.getText().equals("") test2 was still not editable.
You can do this by binding the editable property of test2 to the text property of test.
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
TextField test = new TextField();
TextField test2 = new TextField();
// do the binding
test2.editableProperty().bind(test.textProperty().isEmpty().not());
VBox root = new VBox(20, test, test2);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(50));
primaryStage.setScene(new Scene(root, 300, 150));
primaryStage.setTitle("Example");
primaryStage.show();
}
}
The text property of TextField is a StringProperty. This class has the method isEmpty (inherited by StringExpression) that returns a BooleanBinding that will hold true if the StringProperty's value is empty or null. The not() call negates the value of the BooleanBinding which means test2 will only be editable if test's text is not empty.
Instead of checking all the time you can just listen on changes like this:
test.textProperty().addListener((observable, oldValue, newValue) -> {
if (newValue.equals("")) {
test2.setEditable(false);
}
);
I've come across a somewhat perplexing conundrum. I've recently started to figure out how to work with listeners, thanks to some people on here, and I'm trying to find a way to use them in conjunction with choice/comboboxes to do something tricky. What I want to have happen is, when the user makes a selection from one of six linked boxes containing six choices, it removes that option from the other 5 boxes until either A: the option is changed to one of the remaining ones, or B: the option is changed to a null or default setting (to prevent getting "locked in" after picking, or maybe I can just make a reset button for that purpose). I've got a ChangeListener on each choicebox now, but various things I've tried (switch statements, assigning each answer a boolean, various attempts to use .getItems().remove() in vain, I've been at this a while) Has anyone figured or seen an example of how this could be done? Thanks in advance for any advice, you guys(and gals) have helped me learn by leaps and bounds these past few weeks.
if you want something like this:
I had this code in my program. it is nor really efficient, but was fine for me on a small set of data.
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ChoiceBox;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ConnectedComboBox<T> implements ChangeListener<T> {
private ObservableList<T> items;
private List<ChoiceBox<T>> comboBoxList = new ArrayList<>();
public ConnectedComboBox(ObservableList<T> items){
this.items = items;
if (this.items == null) this.items = FXCollections.observableArrayList();
}
public void addComboBox(ChoiceBox<T> comboBox){
comboBoxList.add(comboBox);
comboBox.valueProperty().addListener(this);
updateSelection();
}
public void removeComboBox(ChoiceBox<T> comboBox){
comboBoxList.remove(comboBox);
comboBox.valueProperty().removeListener(this);
updateSelection();
}
// this boolean needed because we can set combobox Value in updateSelection()
// this will trigger a value listener and update selection one more time => stack overflow
// this behavior occurs only if we have more than one equal item in source ObservableList<T> items list.
private boolean updating = false;
private void updateSelection() {
if (updating) return;
updating = true;
List<T> availableChoices = items.stream().collect(Collectors.toList());
for (ChoiceBox<T> comboBox: comboBoxList){
if (comboBox.getValue()!= null) {
availableChoices.remove(comboBox.getValue());
}
}
for (ChoiceBox<T> comboBox: comboBoxList){
T selectedValue = comboBox.getValue();
ObservableList<T> items = comboBox.getItems();
items.setAll(availableChoices);
if (selectedValue != null) {
items.add(selectedValue);
comboBox.setValue(selectedValue);
}
}
updating = false;
}
#Override
public void changed(ObservableValue<? extends T> observable, T oldValue, T newValue) {
updateSelection();
}
}
And here is how you use it:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ChoiceBox;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class MainFX extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
HBox root = new HBox();
root.setSpacing(10);
ObservableList<String> values = FXCollections.observableArrayList("One", "Two", "Three", "Four","Five");
ChoiceBox<String> combo1 = new ChoiceBox<>();
combo1.setPrefWidth(100);
ChoiceBox<String> combo2 = new ChoiceBox<>();
combo2.setPrefWidth(100);
ChoiceBox<String> combo3 = new ChoiceBox<>();
combo3.setPrefWidth(100);
root.getChildren().addAll(combo1,combo2,combo3);
ConnectedComboBox<String> connectedComboBox = new ConnectedComboBox<>(values);
connectedComboBox.addComboBox(combo1);
connectedComboBox.addComboBox(combo2);
connectedComboBox.addComboBox(combo3);
primaryStage.setScene(new Scene(root,600,600));
primaryStage.show();
}
public static void main(String[] args){
launch(args);
}
}
enter code here
package com.example.registration;
I am trying to move from one activity to another if the user clicks The Button. The Linear layout is set to clikable. The application gets loaded. But when the onClick is not performed for moving on to the next activity.My Code Below
import android.view.View;
import android.view.View.OnClickListener;
.....
public class MainActivity extends Activity implements OnClickListener {
...
protected void onCreate(Bundle savedInstanceState) {
....
findViewById(R.id.myButtonId).setOnClickListener(this);
}
...
public void onClick(View view) {
.. // check view.getId()
//start another activity
Intent intent = new Intent(this, AnotherActivity.class);
startActivity(intent);
...
}
I am trying to make some small additions to some old java code that does not support swing. I need to add a small dialog that contains a panel which has a checkbox and a couple text fields. When the user clicks on the checkbox I want to disable or enable the checkboxes. This part seems to work well but the text fields are not properly getting redrawn. When I click the checkbox the fields do not appear to become enabled but if I then click on the panel or the text field you see that they are enabled (the opposite is also true, when I un-check the checkbox the fields still look enabled until you try and click on them and they become ghosted and do not become selected). I use the setEnabled(boolean) to set the status of the fields. I have tried calling repaint and validate on both the fields and the panel after changing the status and this does not seem to work. I have also tried to have the fields request focus and this did not work. Anyone have any other ideas?
//The class that contains all of this is of type Window
//Declaration of the components
private Panel _inputPanel;
private TextField min , max;
//This method adds to two text fields
public void addMinMaxtextFields(String min, String max) {
TextField minField = new TextField(min);
TextField maxField = new TextField(max);
this.min = minField;
this.max = maxField;
this.min.setEnabled(false);
this.max.setEnabled(false);
_inputPanel.add(minField);
_inputPanel.add(maxField);
}
//listener for the checkbox
public void itemStateChanged(ItemEvent e) {
Component[] components = _inputPanel.getComponents();
min.setEnabled(!min.isEnabled());
min.setVisible(true);
min.validate();
min.repaint();
_inputPanel.validate();
_inputPanel.repaint();
this.pack();
this.setSize(this.getWidth(), this.getHeight());
this.validate();
this.repaint();
/* do nothing */
}
You will need to call update(Graphics g) on Panel after setEnabled(boolean) is called.
check :
http://download-llnw.oracle.com/javase/1.4.2/docs/api/java/awt/Container.html#update(java.awt.Graphics)
I tried following code (built from code you provided), Its working fine.
import java.awt.Checkbox;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
public class CheckUI extends Dialog implements ItemListener {
// The class that contains all of this is of type Window
// Declaration of the components
private Panel _inputPanel;
private TextField min, max;
private Checkbox cb;
public CheckUI(Frame owner, boolean modal) {
super(owner, modal);
_inputPanel = new Panel();
this.add(_inputPanel);
addMinMaxtextFields("min", "max");
}
// This method adds to two text fields
public void addMinMaxtextFields(String min, String max) {
cb = new Checkbox();
cb.addItemListener(this);
TextField minField = new TextField(min);
TextField maxField = new TextField(max);
this.min = minField;
this.max = maxField;
this.min.setEnabled(false);
this.max.setEnabled(false);
_inputPanel.add(minField);
_inputPanel.add(maxField);
_inputPanel.add(cb);
}
// listener for the checkbox
public void itemStateChanged(ItemEvent e) {
Component[] components = _inputPanel.getComponents();
min.setEnabled(!min.isEnabled());
min.setVisible(true);
min.validate();
min.repaint();
_inputPanel.validate();
_inputPanel.repaint();
this.pack();
this.setSize(this.getWidth(), this.getHeight());
this.validate();
this.repaint();
/* do nothing */
}
/**
* #param args
*/
public static void main(String[] args) {
Frame parent = new Frame();
parent.setVisible(true);
parent.setExtendedState(Frame.MAXIMIZED_BOTH);
parent.pack();
CheckUI ui = new CheckUI(parent, true);
ui.pack();
ui.setVisible(true);
}
}