How to get a value from an EventHandler - java

I'm trying to get the value from the Textfield named getText. However, it doesn't let me get the value since it's inside the handler. Is there a way I can return or save this value?
Here's the code:
EventHandler<ActionEvent> handler2 = k -> {
if (!getText.getText().isEmpty()) {
String NameOfFile = getText.getText();
finallyname[0]=NameOfFile;
StringBuilder sb1 = new StringBuilder(NameOfFile);
sb1.append(".txt");
String newStr=sb1.toString();
System.out.println(newStr);
name.setText(newStr);
stage.show();
stage1.close();
theWindow.getChildren().addAll(v1);
r1.setOnMouseClicked(ME -> {
if (ME.getButton().equals(MouseButton.PRIMARY) && ME.getClickCount() == 2) {
try {
Parent newtxtFile = FXMLLoader.load(getClass().getResource("txtFile.fxml"));
Stage stagenew = new Stage();
Scene scenenew = new Scene(newtxtFile);
stagenew.setTitle(getText.getText());
stagenew.setScene(scene);
stagenew.show();
} catch (IOException ex) {
}
}
});
} else {
l2.setTextFill(Color.RED);
l2.setText("Please enter a value first.");
}
};

Related

RadioGroupButton deselect value when button is clicked in Vaadin 14

I've been working on an online exam project and currently adding some multiple choice feature. My problem is, each time I moved to the next question the value from the previous radiogroupbutton is removed/deselect. But still the assigned value of the object is present.
I tried removing/adding the component as well, still the selected value for the RadioGroupButton is missing.
public class TestQuestionaire extends Dialog {
TQCoverageService tqcs = new TQCoverageServiceImpl();
CellItemService cis = new CellItemServiceImpl();
ItemKeyService iks = new ItemKeyServiceImpl();
VerticalLayout mainLayout;
TQCoverage tqCoverage;
List<CellItem> ciList = new ArrayList();
Map<CellItem, CellItemOption> cellItemAnswerMap = new HashMap();
CellItem cellItem;
Binder<CellItem> binder;
private int tqCoverageId;
private int cellItemIndex = 0;
private int cellItemIndexSize = 0;
private int score = 0;
Button next;
Button prev;
String stem;
Paragraph stemHolder;
RadioButtonGroup<CellItemOption> cioGroup;
public TestQuestionaire(int tqCoverageId) {
this.tqCoverageId = tqCoverageId;
tqCoverage = tqcs.findTQCoverage(tqCoverageId);
cellItemIndexSize = tqCoverage.getTotalItems();
for(TQItems tqi : tqcs.findAllTQItems(tqCoverageId)){
cellItem = cis.findCellItem(tqi.getCellItemId());
List<CellItemOption> cioList = cis.findAllItemOptions(tqi.getCellItemId());
cellItem.setCellItemOptionList(cioList);
ItemKey ik = iks.findItemKey(tqi.getItemKeyId());
cellItem.setItemKey(ik);
TQAnswerKey tqak = tqcs.findTQAnswerKeyByTQItem(tqi.getTqItemId());
cellItem.setTQAnswerKey(tqak);
cellItemAnswerMap.put(cellItem, new CellItemOption());
ciList.add(cellItem);
}
stemHolder = new Paragraph();
stemHolder.setWidthFull();
stemHolder.getStyle().set("font-weight", "500");
Hr hr = new Hr();
hr.setWidthFull();
cioGroup = new RadioButtonGroup<>();
cioGroup.setRenderer(new TextRenderer<>(CellItemOption::getCellItemOption));
cioGroup.addThemeVariants(RadioGroupVariant.LUMO_VERTICAL);
cioGroup.addValueChangeListener(event -> {
if(event.getValue() == null){
return;
}
if(!event.getValue().equals(event.getOldValue())){
cellItemAnswerMap.replace(getCellItem(), event.getValue());
}
});
mainLayout = new VerticalLayout(stemHolder, hr, cioGroup);
mainLayout.setWidth("600px");
hr = new Hr();
hr.setWidthFull();
mainLayout.add(hr);
binder = new Binder();
binder.forField(cioGroup)
.bind(CellItem::getCellItemOption, CellItem::setCellItemOption);
changeCellItem();
prev = new Button(VaadinIcon.BACKWARDS.create());
prev.addClickListener(event -> {
cellItemIndex--;
if(cellItemIndex == 0){
prev.setEnabled(false);
next.setEnabled(true);
} else {
prev.setEnabled(true);
next.setEnabled(true);
}
changeCellItem();
});
prev.setEnabled(false);
next = new Button(VaadinIcon.FORWARD.create());
next.getStyle().set("margin-left", "490px");
next.addClickListener(event -> {
cellItemIndex++;
if((cellItemIndex + 1) == cellItemIndexSize){
next.setEnabled(false);
prev.setEnabled(true);
} else {
next.setEnabled(true);
prev.setEnabled(true);
}
changeCellItem();
});
//this button is only to test if the current value for radiobuttongroup is removed/deselect when clicked!!
mainLayout.add(new Button("TEST", event -> {
changeCellItem();
}));
HorizontalLayout buttons = new HorizontalLayout(prev, next);
buttons.setWidthFull();
buttons.setJustifyContentMode(FlexComponent.JustifyContentMode.START);
mainLayout.add(buttons);
add(mainLayout);
open();
}
//refresh components for new/previous set if item
private void changeCellItem(){
stemHolder.removeAll();
cellItem = ciList.get(getCellItemIndex());
stem = cellItem.getItem().replace("{key}", cellItem.getItemKey().getItemKey());
stemHolder.add(stem);
cioGroup.clear();
cioGroup.setItems(cellItem.getCellItemOptionList());
cellItem.setCellItemOption(cellItemAnswerMap.get(cellItem));
binder.readBean(cellItem);
//binder.setBean(cellItem);
}
public TQCoverage getTQCoverage() {
return tqCoverage;
}
public CellItem getCellItem() {
return cellItem;
}
public int getCellItemIndex() {
return cellItemIndex;
}
public int getCellItemIndexSize() {
return cellItemIndexSize;
}
}

How to transfer string between methods (Java)

Essentially, I'm trying to collect data for a string and use it in another method. Whatever I've tried hasn't seemed to work. Please check out my code and tell me what to do.
I've tried to declare the string as a public string, but since it is in a method I can't.
My goal is to transfer the string "application_1" to button3's setOnAction method.
#Override
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
window.setTitle("myDesktop");
window.setOnCloseRequest(e -> closeProgram());
button = new Button("Setup MyDesktop");
button3 = new Button("Start Test Application");
button2 = new Button("Choose Wheel Applications");
button2.setOnAction(e -> {
JFileChooser jfc = new JFileChooser();
jfc.showDialog(null, "Please select a file.");
jfc.setVisible(true);
File filename = jfc.getSelectedFile();
String application_1 = filename.getName();
if (application_1.endsWith(".exe")) {
System.out.println("File successfully chosen!");
} else {
System.out.println("File is not an application!");
System.out.println("Please choose another file!");
System.out.println("Issue Alert Box here...");
}
if (application_1 == null) {
System.out.println("No file selected!");
}
});
button.setOnAction(e -> {
AlertBox.display("Alert", "Save file?");
});
button3.setOnAction(e -> {
Runtime runtime = Runtime.getRuntime();
try {
Process process = runtime.exec("name_of_file");
} catch (IOException e1) {
e1.printStackTrace();
}
});
I want the string to be able to be used by the code
button3.setOnAction(e -> {
// code
});
Should work:
#Override
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
window.setTitle("myDesktop");
window.setOnCloseRequest(e -> closeProgram());
String application_1 = "";
button = new Button("Setup MyDesktop");
button3 = new Button("Start Test Application");
button2 = new Button("Choose Wheel Applications");
button2.setOnAction(e -> {
JFileChooser jfc = new JFileChooser();
jfc.showDialog(null, "Please select a file.");
jfc.setVisible(true);
File filename = jfc.getSelectedFile();
application_1 = filename.getName();
if (application_1.endsWith(".exe")) {
System.out.println("File successfully chosen!");
} else {
System.out.println("File is not an application!");
System.out.println("Please choose another file!");
System.out.println("Issue Alert Box here...");
}
if (application_1 == null) {
System.out.println("No file selected!");
}
});
button.setOnAction(e -> {
AlertBox.display("Alert", "Save file?");
});
button3.setOnAction(e -> {
Runtime runtime = Runtime.getRuntime();
System.out.println(application_1); //here you can use the variable
try {
Process process = runtime.exec("name_of_file");
} catch (IOException e1) {
e1.printStackTrace();
}
});
Since you don't have control over the actual event that's created when the button is hit you cannot pass it directly (well, maybe you could add a tag to the button or something similar - I never used javafx).
But nothing prevents you from introducing an object-level variable to hold your string(s).
class YourClass {
private String myString = "";
public void start(Stage primaryStage) throws Exception {
// ...
button2.setOnAction(e -> {
this.myString = "application_1";
});
// ...
button3.setOnAction(e -> {
System.out.println(this.myString);
});
}
}
Alternatively, if your variable is final or effectively final you can just use it in your anonymous function:
class YourClass {
public void start(Stage primaryStage) throws Exception {
// ...
final String myString = "application_1";
// ...
button3.setOnAction(e -> {
System.out.println(myString);
});
}
}

Introspection (JavaFx)

after having made quite a lot of searches, I leave it up to you.
Here is in my application JavaFx, I use the introspection to generate a gridPane automatically (that I insert then into Dialog). Thus I have TableView, when the user doubles click above, it generates Dialog containing the columns of this TableView.
In this Dialog, thus there is TextFields which allow to modify the values of fields in TableView.
But well, I cannot get back the value of my attributes by means of the introspection, and how make get back the value of the textFields which were created thanks to the introspection?
There is my introspection method :
public static GridPane analyserChamp(Etudiant etu) {
List<String> list = new ArrayList<>();
Class<? extends Etudiant> classPixel = etu.getClass();
Field attribut[] = classPixel.getDeclaredFields();
GridPane gp = new GridPane();
int i=0;
for(Field p : attribut) {
list.add(p.getName());
Label lab = new Label();
if(!p.getName().equals("classe")) {
TextField l = new TextField();
lab.setText(p.getName());
gp.add(l, 1, i);
}else {
ComboBox<String> cb = new ComboBox<String>();
cb.getItems().addAll("1Bi","2Bi","3Bi");
gp.add(cb, 1, i);
}
gp.add(lab, 0, i);
i++;
}
return gp;
}
Here is the code where I call on to the method of introspection :
if(e.getClickCount() == 2) {
Dialog<Etudiant> dialog = new Dialog<>();
Etudiant test = tableViewEtudiant.getSelectionModel().getSelectedItems().get(0);
if(test!=null) {
dialog.setTitle("Editor");
dialog.setHeaderText("You can update your question");
dialog.getDialogPane().setContent(Analysateur.analyserChamp(test));
ButtonType buttonCancel = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE);
ButtonType buttonOk = new ButtonType("Ok", ButtonData.OK_DONE);
dialog.getDialogPane().getButtonTypes().addAll(buttonOk,buttonCancel);
//Confirmation of the edition
Optional<Etudiant> result = dialog.showAndWait();
//Edition of the question in the gson file
GridPane tmp = Analysateur.analyserChamp(test);
if(result.isPresent()) {
// Here ?????
}
}
Thank in advance ;)
There are many ways of solving this, for example, you can use the userData property to store the key of the attributes, so you can iterate later over the GridPane children and obtain each value in the Dialog result converter.
When you introspect the class Etudiant:
if(!p.getName().equals("classe")) {
TextField l = new TextField();
l.setUserData(p.getName()); //Store the attribute name in the TextField
lab.setText(p.getName());
gp.add(l, 1, i);
}else {
ComboBox<String> cb = new ComboBox<String>();
cb.setUserData(p.getName()); //Store the attribute name in the ComboBox
cb.getItems().addAll("1Bi","2Bi","3Bi");
gp.add(cb, 1, i);
}
When you creat the Dialog:
Dialog<Etudiant> dialog = new Dialog<>();
...
GridPane content = Analysateur.analyserChamp(test); //Keep the content accesible
...
dialog.getDialogPane().setContent(content);
...
dialog.setResultConverter(button -> { //Convert the result
Etudiant result = new Etudiant();
for (Node child : content.getChildren()) { //Iterate over the GridPane children
if (child instanceof TextField) {
String attribute = ((TextField)child).getUserData();
String value = ((TextField)child).getTest();
//Set the value in the result attribute via instrospection
}
if (child instanceof ComboBox) {
//Do the same with combos
}
}
});
Store a Supplier for getting the value of the input for a field in a Map<Field, Supplier<?>>. This way you could go through the entries of the map and retrieve the values for the assignments:
public class ReflectionDialog<T> extends Dialog<T> {
public ReflectionDialog(Class<T> type, Supplier<T> factory) throws IllegalAccessException {
GridPane gp = new GridPane();
Field[] fields = type.getDeclaredFields();
// stores getters for result value
final Map<Field, Supplier<?>> results = new HashMap<>();
int i = 0;
for (Field field : fields) {
if (String.class.equals(field.getType())) {
String name = field.getName();
Node input;
Supplier<?> getter;
if ("classe".equals(name)) {
ComboBox<String> cb = new ComboBox<>();
cb.getItems().addAll("1Bi", "2Bi", "3Bi");
getter = cb::getValue;
input = cb;
} else {
TextField l = new TextField();
getter = l::getText;
input = l;
}
results.put(field, getter);
gp.addRow(i, new Label(name), input);
i++;
}
}
getDialogPane().setContent(gp);
getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
setResultConverter(buttonType -> {
if (buttonType == ButtonType.OK) {
// create & initialize new object
final T object = factory.get();
results.forEach((k, v) -> {
try {
k.set(object, v.get());
} catch (IllegalAccessException ex) {
throw new IllegalStateException(ex);
}
});
return object;
} else {
return null;
}
});
}
}
public class A {
String classe;
String value;
#Override
public String toString() {
return "A{" + "classe=" + classe + ", value=" + value + '}';
}
}
ReflectionDialog<A> dialog = new ReflectionDialog<>(A.class, A::new);
A result = dialog.showAndWait().orElse(null);
System.out.println(result);

How to configure Progress Bar and Progress Indicator of javaFx?

I am trying to add a slider on my page like progress bar. But my code is not working well.
My task is when I am going to copy something from one location to another I want to display a progress bar on my page.
So in javaFx I wrote following task but it is not working well. That code runs but I want show the work in percentage like 30%, 50% and "finish". But my code fails to gives me like requirement so please help me.
My code is:
1.Declaration of progress bar and progress indicator
#FXML
final ProgressBar progressBar = new ProgressBar();
#FXML
final ProgressIndicator progressIndicator = new ProgressIndicator();
2.Assign values when I click on copy button.
#FXML
private void handleOnClickButtonAction(MouseEvent event) {
if (fromLabel.getText().isEmpty()
|| toLabel.getText().isEmpty()
|| fromLabel.getText().equalsIgnoreCase("No Directory Selected")
|| toLabel.getText().equalsIgnoreCase("No Directory Selected")) {
// Nothing
} else {
progressBar.setProgress(0.1f);
progressIndicator.setProgress(progressBar.getProgress());
this.directoryCount.setText("Please Wait !!!");
}
}
This code shows me only 10% completion an then directly shows "done", but I want whole process in percentage like 10,20,30,.. etc and then "done".
My copy code:
double i = 1;
while (rst.next()) {
File srcDirFile = new File(fromLabel.getText() + "/" + rst.getString("nugget_media_files"));
File dstDirFile = new File(toLabel.getText() + "/" + rst.getString("nugget_media_files"));
File dstDir = new File(toLabel.getText() + "/" + rst.getString("nugget_directory"));
if (srcDirFile.lastModified() > dstDirFile.lastModified()
|| srcDirFile.length() != dstDirFile.length()) {
copyDirectory(srcDirFile, dstDirFile, dstDir);
}
this.currentNuggetCount = i / this.nuggetFolderSize;
System.out.println("Nugget Count : " + this.currentNuggetCount);
Platform.runLater(new Runnable() {
#Override
public void run() {
progressBar.setProgress(1.0f);
progressIndicator.setProgress(progressBar.getProgress());
}
});
++i;
}
This is the copyDirectory method:
private static void copyDirectory(File srcDir, File dstDir,File destNugget) {
System.out.println(srcDir+" >> "+dstDir);
if(!destNugget.exists()) {
destNugget.mkdirs();
}
if (srcDir.isDirectory()) {
if (!dstDir.exists()) {
dstDir.mkdirs();
}
String[] children = srcDir.list();
for (int i=0; i<children.length; i++) {
copyDirectory(new File(srcDir, children[i]),
new File(dstDir, children[i]),
destNugget);
}
} else {
InputStream in = null;
try {
in = new FileInputStream(srcDir);
OutputStream out = new FileOutputStream(dstDir);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException ex) {
System.out.println("Exceptio "+ex);
} finally {
try {
in.close();
} catch (IOException ex) {
System.out.println("Exceptio "+ex);
}
}
}
}
Try this code. It will give you Progress bar with progress indicator which depends on the slider control.
public class Main extends Application {
#Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Progress Controls");
final Slider slider = new Slider();
slider.setMin(0);
slider.setMax(50);
final ProgressBar pb = new ProgressBar(0);
final ProgressIndicator pi = new ProgressIndicator(0);
slider.valueProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue<? extends Number> ov,
Number old_val, Number new_val) {
pb.setProgress(new_val.doubleValue()/50);
pi.setProgress(new_val.doubleValue()/50);
}
});
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(slider, pb, pi);
scene.setRoot(hb);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
You must enter your code inside a Task and set within UpdateProgress method. Before you run the Task you have to set progressBar.progressProperty (). Bind (task.progressProperty ());
This is an example:
TaskTest

Jtable content is visible through different tab

I have JTabbedPane with 4 tabs. JtabbedPane is situated on a JLayeredPane. 1st and 4th tab contain JTable with custom models. Each of the tables is being refreshed every 5-10 seconds.
When 1st tab is active, and JTable on 4th has just finished refreshing, I can see content of the 4th on the 1st. Look at the screenshot.
When I click on the other tab, or minimize window, that strange effect is gone. Till the next refresh of that table on 4th tab. Refreshing is done using Future<> object.
I used Swing GUI builder in Netbeans, so I have huge amount of code. Would post any piece which could be useful.
I tried to revalidate jTabbedPane, is had no effect. Both tables and jScrollPanes has opaque property set to true. So I tried to use SwingUtilities.invokeLater(). It helped a little bit - now first content update goes well, but later - the same problem.
2nd table model has method to update it's content
public void setData(LinkedList<Object[]> __rows) {
NewDevsTableModel.__rows = __rows;
fireTableDataChanged();
}
It is used here (I added SwingUtilities here)
static class checkNew implements Callable<Boolean> {
#Override
public Boolean call() {
ServiceMessage sm = ServiceMessage.getNewList();
try {
connect();
os.write(sm.serialize());
for (int i=0; i<10; i++) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {}
if (is.available() > 0) {
break;
}
if (i == 9) {
disconnect();
return false;
}
}
byte[] actByte = new byte[is.available()];
is.read(actByte);
try {
sm = ServiceMessage.Deserialize(actByte); //may be there are no new devices
if (sm.getType() == ServiceMessageType.NODATA) {
MainWindow.jTabbedPane1.setEnabledAt(3, false);
if (MainWindow.jTabbedPane1.getSelectedIndex() == 3) {
MainWindow.jTabbedPane1.setSelectedIndex(0);
}
return true;
} else {
return false; //wrong answer type
}
} catch (ClassCastException | StreamCorruptedException e) {
//remember selection and scroll
final int scroll = MainWindow.jScrollPane3.getVerticalScrollBar().getValue();
final int[] rows = MainWindow.newDevsTable.getSelectedRows();
int col = MainWindow.devicesTable.getSelectedColumn();
String[] parts = new String(actByte).split("\n");
final LinkedList<Object[]> l = new LinkedList();
for (int i=0; i<parts.length; i++) {
String[] dev = parts[i].split(";", -1);
String descr = dev[2];
boolean iptype = (!dev[3].equals("-"));
String address = dev[4];
boolean atmtype = (dev[5].equals("+"));
if (MainWindow.newDevsTable.getRowCount() >= (i+1)) {
if ((MainWindow.newDevsTable.getValueAt(i, 4) != null) && !MainWindow.newDevsTable.getValueAt(i, 4).equals("")) {
descr = MainWindow.newDevsTable.getValueAt(i, 4).toString();
}
}
Object[] o = {dev[0], dev[1], MainWindow.language[180], MainWindow.language[4], descr, iptype, address, atmtype};
l.add(o);
}
if (!l.isEmpty()) {
SwingUtilities.invokeLater( new Runnable() {
#Override
public void run() {
MainWindow.newDevsPanel.setVisible(true);
MainWindow.jTabbedPane1.setEnabledAt(3, true);
((NewDevsTableModel)MainWindow.newDevsTable.getModel()).setData(l);
ButtonColumn buttonColumn = new ButtonColumn(MainWindow.newDevsTable, addAction, 2, true);
buttonColumn = new ButtonColumn(MainWindow.newDevsTable, rejAction, 3, false);
//put selection back
for (int i=0; i<rows.length; i++) {
MainWindow.newDevsTable.addRowSelectionInterval(rows[i], rows[i]);
}
MainWindow.jScrollPane3.getVerticalScrollBar().setValue(scroll);
}
});
} else {
MainWindow.jTabbedPane1.setEnabledAt(3, false);
if (MainWindow.jTabbedPane1.getSelectedIndex() == 3) {
MainWindow.jTabbedPane1.setSelectedIndex(0);
}
}
return true;
}
} catch (IOException e) {
disconnect();
return false;
} catch (ClassNotFoundException e) {
return false;
}
}
}
I submit the task this way
public static Future<Boolean> checkNewDevices() {
final Future<Boolean> task;
task = service.submit(new checkNew());
return task;
}
To refresh automatically I use separate thread
public class CheckNewPassThread extends Thread {
int pause = 10000;
#Override
public void run() {
for (;;) {
HostConnection.checkNewDevices();
try {
Thread.sleep(pause);
} catch (InterruptedException e) {}
}
}
}
Which is started when the window is opened
private void formWindowOpened(java.awt.event.WindowEvent evt) {
HostConnection.getData();
HostConnection.getDeviceAddress();
RefreshData refreshThread = new RefreshData();
refreshThread.start();
new CheckNewPassThread().start();
}
OMG, the problem was in calling jTabbedPane.setEnabledAt(3, true) to already enabled tab. Swing is fascinating

Categories