no callback is received after clicking on the button - java

after clicking on the button that appears as a result of the first piece of code, the if check fails, that is, the callBack Data is not returned
#Override
public void onUpdateReceived(Update update) {
InlineKeyboardButton button = new InlineKeyboardButton();
button.setText("button");
button.setCallbackData("data");
List<InlineKeyboardButton> buttons = new ArrayList<>();
buttons.add(button);
List<List<InlineKeyboardButton>> list = new ArrayList<>();
list.add(buttons);
InlineKeyboardMarkup markup = new InlineKeyboardMarkup();
markup.setKeyboard(list);
var s = SendMessage.builder()
.chatId(String.valueOf(update.getMessage().getChatId()))
.text("text")
.replyMarkup(markup)
.build();
try {
execute(s);
} catch (TelegramApiException e) {
throw new RuntimeException(e);
}
if (update.hasCallbackQuery()) {
try {
execute(new SendMessage(String.valueOf(update.getUpdateId()),
update.getMessage().getText())
);
} catch (TelegramApiException e) {
throw new RuntimeException(e);
}
}
}

Related

How to get a value from an EventHandler

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.");
}
};

How do I pass a variable from a try to an action event?

try(FileInputStream fis = (new FileInputStream("*FILE*"))){
Player player = new Player(fis);
Button btn = new Button();
btn.setText("Start");
Button btn2 = new Button();
btn2.setText("Stop");
}catch(JavaLayerException | IOException e ){
e.printStackTrace();
}
btn.setOnAction((ActionEvent event) -> {
this.player = player;
try{
new playMusic(player).start();
}catch(Exception e){
e.printStackTrace();
}
});
btn2.setOnAction((ActionEvent event)->{
player.close();
});
It feels like this should be something really simple but I couldn't find anything anywhere
Either you move the code accessing the variable inside the try block or you declare the variable outside of the try block and make sure it's initialized when the event handler is registered.
final Player player;
try(FileInputStream fis = new FileInputStream("*FILE*")){
player = new Player(fis);
} catch(JavaLayerException | IOException e){
e.printStackTrace();
// prevent access to uninitialized player variable by exiting the method
throw new RuntimeException(e);
}
Button btn = new Button();
btn.setText("Start");
Button btn2 = new Button();
btn2.setText("Stop");
btn.setOnAction((ActionEvent event) -> {
this.player = player;
try{
new playMusic(player).start();
} catch(Exception e){
e.printStackTrace();
}
});
btn2.setOnAction((ActionEvent event)->{
player.close();
});
Instead of
throw new RuntimeException(e);
you could also exit the method gracefully using
return;
instead.
Edit
If Player is not reading all the code in the constructor, you must not close it. try-with-resources does this though. Change to a try catch
try {
FileInputStream fis = new FileInputStream("*FILE*");
try {
player = new Player(fis);
} catch(JavaLayerException | IOException e) {
e.printStackTrace();
fis.close(); // close stream on player creation failure
// prevent access to uninitialized player variable by exiting the method
throw new RuntimeException(e);
}
} catch(IOException e){
e.printStackTrace();
// prevent access to uninitialized player variable by exiting the method
throw new RuntimeException(e);
}

Why can't I use setText() under Button event?

So I am remaking my kinda complex console program to GUI. However, I am very unexperienced JavaFX user.
Label cityNameLabel = (Label) scene.lookup("#cityNameLabel");
cityNameLabel.setText("No text");
Button startButton = (Button) scene.lookup("#startButton");
Here I have my Label successfully initiated. At this moment I can still use cityNameLabel.setText(); and it is gonna work.
This continues:
startButton.setOnAction(e -> {
String enteredUrl = linkField.getText();
if(isValidUrl(enteredUrl)) {
try {
cityNameLabel.setText("Test");
doJob(enteredUrl, cityNameLabel);
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}.........
When I try to change the label here it won't happen. What I actually need to do is to reference the cityNamelLabel to doJob() method and I want to doJob() method to change it (once it finds the name of the city).
Can anyone give a me a solution that would allow me to do what I want to do? (changing it afterwards from doJob();). Thank you!
EDIT: Here I post my attemp of minimal version. I hope it is enough
package net.maty;
public class Katastr extends Application {
final String programName = "KatastRED";
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage mainStage) throws Exception {
try {
mainStage.setTitle(programName);
mainStage.setResizable(false);
BorderPane root = (BorderPane)FXMLLoader.load(getClass().getResource("Katastr.fxml"));
Scene scene = new Scene(root,800,500);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
ChoiceBox threadNumberBox = (ChoiceBox) scene.lookup("#threadNumberBox");
threadNumberBox.getSelectionModel().select(5);
TextField linkField = (TextField) scene.lookup("#linkField");
//debug
linkField.setText("https://regiony.kurzy.cz/katastr/stary-kolin/objekty?strana=");
//
Text cityNameText = (Text) scene.lookup("#cityNameText");
Button startButton = (Button) scene.lookup("#startButton");
//HERE IS THE THING. EVERYTHING WORKS WELL EXCEPT THE FACT I CANT CHANGE CITYNAMETEXT
startButton.setOnAction(e -> {
String enteredUrl = linkField.getText();
if(isValidUrl(enteredUrl)) {
try {
cityNameText.setText("Example that will not show because it doesnt work.");
doJob(enteredUrl, cityNameText);
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
else {
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Chyba!");
alert.setHeaderText(null);
alert.setContentText("Chybně zadané URL!");
alert.showAndWait();
}
});
mainStage.setScene(scene);
mainStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void doJob(String validatedUrl, Text cityNameText) throws IOException, InterruptedException {
Scanner in = new Scanner(System.in);
String url = validatedUrl;
String cityName = getCityName(url);
cityNameText.setText(cityName);
List<String> parcelLinks = getParcelLinks(url);.....
}
public static List<String> getParcelLinks(String url) throws IOException{
}
public static List<String> getAdressesFromPage(Document doc) {
}
public static List<String> createParcelUrls(List<String> links) throws IOException {
}
public static boolean isValidUrl(String url) {
}
public static String getCityName(String url) throws IOException {
}
}

Update TextFlow from another class JavaFx

I'm here with my JavaFx app.
I have two class:
I start these class in two different Thread. Because server is blockable.
My UI class ( Called Main ( I know i need to change this)).
A Server class ( Called Serveur )).
In my Server Class when i receive bytes with a ServerSocket.
I need to update a TextFlow (called flowMessafe) in my UI class :
with flowMessage.getChildren().add(); I can update this TextFlow without problem in my UI class.
But i my Server class i can't.
EDIT : I try all the things, but i think i found a big problem. I update the wrong instance of my javafx app. I change the code with current code
He is a part of my server code
My Server Constructor
public Serveur(Mediator med){
this.med=med;
try {
lancer();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Loop to catch message or file.
for(;;){
try {
Thread.sleep(1L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Attente de communication ...");
try {
socket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("Can't accept client connection. ");
}
try {
in = socket.getInputStream();
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
byte[] bytes = new byte[16*1024];
while ((count = in.read(bytes)) > 0) {}
String mode = new String(bytes);
String[] split = mode.split(";");
if(split[0].compareTo("Message")==0){
recevoirMessage();
} else if(split[0].compareTo("Fichier")==0){
recevoirFichier(split[2]);
}
in.close();
socket.close();
}
When i receive a message i go to this function :
public void recevoirMessage() {
output = new ByteArrayOutputStream();
try {
socket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("Can't accept client connection. ");
}
try {
in = socket.getInputStream();
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
byte[] bytes = new byte[16*1024];
try {
while ((count = in.read(bytes)) > 0) {}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Message reçus");
String recu = "Message : "+new String(bytes);
System.out.println(recu);
Platform.runLater(() -> {
Label mes = new Label(new String(bytes));
med.cli.flowMessage.getChildren().add(mes);
});
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And in my main i have only empty constructor like
public Main(){}
In my UI class i have this to create my App :
'#Override
public void start(Stage primaryStage) {
try {
this.pStage = primaryStage;
this.pStage = new Stage();
idPane = new BorderPane();
Parent page;
page = FXMLLoader.load(getClass().getResource("/application/application.fxml"));
this.pStage.setTitle("Messagerie");
Scene scene = new Scene(page);
flowMessage = new TextFlow();
idContenuMessage= new ChoiceBox<String>();
scrollPane= new ScrollPane();
//flowMessage = new TextFlow();
String css = this.getClass().getResource("application.css").
toExternalForm();
scene.getStylesheets().clear();
scene.getStylesheets().add(css);
this.pStage.setScene(scene);
this.pStage.setResizable(false);
this.pStage.show();
this.pStage.setOnCloseRequest(event -> {
Serveur.close();
});
} catch (IOException e) {
e.printStackTrace();
}
}'
And i don't know how to update my UI TextFlow in my server Class.
I saw different things like the Mediator Pattern, i try this but it didn't work ( maybe i do something wrong ).
I start my app with this class :
package communication;
import application.Main;
import javafx.application.Application;
import javafx.stage.Stage;
public class Mediator extends Application implements Runnable {
private Serveur serv;
public Main cli;
public Thread thread;
private Stage primaryStage;
public static void main(String args[]){
launch(args);
}
public Mediator(){
cli = new Main();
thread = new Thread(this,"serv");
thread.start();
}
#Override
public void run() {
setServ(new Serveur(this));
}
#Override
public void start(Stage stage) throws Exception {
primaryStage = stage;
cli.start(primaryStage);
}
public Serveur getServ() {
return serv;
}
public void setServ(Serveur serv) {
this.serv = serv;
}
}
Thanks for Helping.
I would use Platform.runLater() to put your GUI changes on the Javafx application thread, e.g.
public void recevoirMessage() {
output = new ByteArrayOutputStream();
try {
socket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("Can't accept client connection. ");
}
try {
in = socket.getInputStream();
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
byte[] bytes = new byte[16*1024];
try {
while ((count = in.read(bytes)) > 0) {}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Message reçus");
String recu = "Message : "+new String(bytes);
System.out.println(recu);
//inserted here
Platform.runLater(new Runnable() {
#Override public void run() {
//HERE I WANT TO UPDATE MY TEXTFLOW
}
});
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Firstly TextFlow does not have text property so you can't set that value to it. Add Text object to text flow:
Text text = new Text();
flowMessage = new TextFlow(text);
Then create StringProperty, bind it to Text component textProperty and update this value in Server class.
Application class:
public class Mediator extends Application implements Runnable {
private Serveur serv;
public Main cli;
private StringProperty textProperty = new SimpleStringProperty("text");
public Thread thread;
private Stage primaryStage;
public static void main(String args[]){
launch(args);
}
public Mediator(){
cli = new Main(this,textProperty);
thread = new Thread(this,"serv");
thread.start();
}
#Override
public void run() {
serv = new Serveur(this,textProperty);
}
#Override
public void start(Stage stage) throws Exception {
primaryStage = stage;
cli.start(primaryStage);
}
}
Pass textProperty to Main and Serveur classes.
cli = new Main(this, textProperty);
serv = new Serveur(this, textProperty);
Bind text property to Text component:
text.textProperty().bind(textProperty);
Finally update textProperty in JavaFX Application Thread in your Serveur class:
public void recevoirMessage() {
output = new ByteArrayOutputStream();
try {
socket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("Can't accept client connection. ");
}
try {
in = socket.getInputStream();
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
byte[] bytes = new byte[16*1024];
try {
while ((count = in.read(bytes)) > 0) {}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Message reçus");
String recu = "Message : "+new String(bytes);
System.out.println(recu);
//inserted here
Platform.runLater(new Runnable() {
#Override public void run() {
//HERE I WANT TO UPDATE MY TEXTFLOW
textProperty.setValue(new String(bytes));
}
});
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Why do JButtons that open webpages only work the first time one is clicked and then get deactivated?

I have a set of JButtons, each of which opens a separate YouTube video webpage. When first running the program, I can click on any ONE button and get the video page. When I try to get another video page with a button click, it doesn't work - in fact, all the buttons are deactivated. This is the case whether or not I close the video webpage.
How can I keep all the buttons activated? Thanks in advance.
Here's the code for reference. The button links and tags are populated from a text file.
//import statements
public class VideoRecord extends JFrame {
private File videoRecordFile;
public VideoRecord() throws FileNotFoundException {
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new GridLayout(2,2));
setSize(new Dimension(500, 500));
videoRecordFile = new File("videorecord.txt");
getButtons();
pack();
}
public void getButtons() throws FileNotFoundException {
Scanner input = new Scanner(videoRecordFile);
while (input.hasNextLine()) {
Scanner lineInput = new Scanner(input.nextLine());
while (lineInput.hasNext()) {
final String urlString = lineInput.next();
String buttonText = lineInput.next();
JButton btn = new JButton(buttonText);
add(btn);
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
URL videoURL = new URL(urlString);
URLConnection videoConnection = videoURL.openConnection();
videoConnection.connect();
openWebpage(videoURL);
}
catch (MalformedURLException mue) {}
catch (IOException ioe) {}
setEnabled(false);
}
});
}
}
}
public static void openWebpage(URI uri) {
Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
try {
desktop.browse(uri);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void openWebpage(URL url) {
try {
openWebpage(url.toURI());
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws FileNotFoundException {
VideoRecord vr = new VideoRecord();
}
}
Take a second to look at you code...
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
URL videoURL = new URL(urlString);
URLConnection videoConnection = videoURL.openConnection();
videoConnection.connect();
openWebpage(videoURL);
}
catch (MalformedURLException mue) {}
catch (IOException ioe) {}
setEnabled(false);
}
});
When you click a button you call setEnabled(false);...
This has actually disable the frame, not the button that was clicked...
Try using ((JButton)e.getSource()).setEnabled(false) instead
Don't throw away you Exceptions blindly, they provide important and useful information that can help solve problems

Categories