want some help to get the bubble chat for the text inside the textarea using javafx, so i have tried to add other methods like left speech bubble and right speech bubble, but thats not working out. so i want the text inside a bubble.
private void initComponents(VBox root) {
incoming = new TextArea();
double height = 500;
double width = 300;
incoming.setPrefHeight(height);
incoming.setPrefWidth(width);
incoming.setFont(Font.font ("Verdana", 15));
incoming.setEditable(false);
incoming.setFocusTraversable(false);
incoming.setBorder((new Border(
new BorderStroke(Color.AQUA, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, BorderWidths.DEFAULT))));
incoming.setStyle(
"-fx-focus-color: -fx-control-inner-background ; -fx-faint-focus-color: -fx-control-inner-background ; -fx-background-image: url(file:Airbus.jpg)");
root.getChildren().add(incoming);
outgoing = new TextField();
outgoing.setFont(Font.font ("Verdana", 15));
root.getChildren().add(outgoing);
root.setAlignment(Pos.CENTER);
send = new Button("SEND");
send.setOnAction(e -> {
String text = outgoing.getText();
if (text.length() > 0) {
incoming.appendText(userName + ": " + text + "\n");
outgoing.selectAll();
writer.println(outgoing.getText());
writer.flush();
}
outgoing.requestFocus();
outgoing.clear();
});
outgoing.setOnKeyPressed(ke -> {
if (ke.getCode() == KeyCode.ENTER) {
send.fire();
}
});
send.setPrefSize(WIDTH, 30);
root.getChildren().add(send);
userName = WindowUtils.buildTextDialog("What is your name?", "Please enter your name :", "Name");
//greet user:
incoming.appendText("AirBot" + ": Your name " + userName + "? I'm taking notes now...\n");
}
Related
How can i make custom Prompt?
I tried with code below..
public static string ShowDialog(string text, string caption) {
Form prompt = new Form() {
Width = 500,
Height = 150,
FormBorderStyle = FormBorderStyle.FixedDialog,
Text = caption,
StartPosition = FormStartPosition.CenterScreen
};
Label textLabel = new Label() { Left = 50, Top = 20, Text = text };
TextBox textBox = new TextBox() { Left = 50, Top = 50, Width = 400 };
Button confirmation = new Button() { Text = "Ok", Left = 350, Width = 100, Top = 70, DialogResult = DialogResult.OK };
confirmation.Click += (sender, e) => { prompt.Close(); };
prompt.Controls.Add(textBox);
prompt.Controls.Add(confirmation);
prompt.Controls.Add(textLabel);
prompt.AcceptButton = confirmation;
return prompt.ShowDialog() == DialogResult.OK ? textBox.Text : "";
}
And then am using it like below
public bool OnJSDialog(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, CefJsDialogType dialogType, string messageText, string defaultPromptText, IJsDialogCallback callback, ref bool suppressMessage) {
if(dialogType.ToString() == "Prompt") {
//Form prompt = ShowDialogClass.ShowDialog("as", "asd");
string promptValue = Components.ShowDialog("Test", "123");
if (promptValue != "") {
callback.Continue(true, promptValue);
} else {
callback.Continue(false, "");
};
};
But i am getting error.
System.InvalidOperationException: 'Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on.'
return false;
}
How can i implement this dialog to show custom prompt?
Few months too late but, here you go.
You are trying to create a new Form(your prompt form) inside another thread. In this case your CEF browser thread that will create a object from class IJsDialogHandler will be on another thread than the prompt message thread so you have to Cross the thread to access it.
The way you do this is "Invoke"(saying something like "wo wo don't worry, i know what i'm doing"). When you use "Invoke" your asking for a witness, well that witness should have the same kind of capabilities as your prompt message box form so.... in this case form that creates the CEF browser. so the code should be something like this
public bool OnJSDialog(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, CefJsDialogType dialogType, string messageText, string defaultPromptText, IJsDialogCallback callback, ref bool suppressMessage) {
if(dialogType.ToString() == "Prompt") {
if (ParentForm.InvokeRequired)
{
ParentForm.Invoke((MethodInvoker)delegate ()
{
string promptValue = Components.ShowDialog(messageText, "Prompt Message");
if (promptValue != "") {
callback.Continue(true, promptValue);
} else {
callback.Continue(false);
}
}
}
suppressMessage = false;
return true;
}
}
ParentForm should be changed to the name of the form that initialize the CEF browser.
I write my app using JavaFX for GUI. I need put listview in interface while app will get colored messages (from other API, I already has converter). What I need put in listview, what can support multicolored text? I need many then one color in one list entry.
I already try use TextFlow, but nothing changed... Text is white.
// In converter (list of Messages to TextFlow)
public static TextFlow getTextFlow(List<Message> list) {
TextFlow flow = new TextFlow();
for(Message msg : list) {
Text text = new Text(msg.getFullText());
MessageStyle style = msg.getStyle();
ChatColor color = style.getColor();
String textstyle = "";
if(!(color.equals(ChatColor.NONE) || color.equals(ChatColor.NONE)))
textstyle += "-fx-text-fill: #" + TextColor.valueOf(color.name()).getHex() + ";";
System.out.println(textstyle);
for(ChatFormat f : style.getFormats()) {
System.out.println(f.toString());
switch (f) {
case BOLD:
if(!textstyle.equals("-fx-font-weight: bold;")) textstyle += " ";
textstyle += "";
break;
case ITALIC:
if(!textstyle.equals("-fx-font-style: italic;")) textstyle += " ";
textstyle += "";
break;
case STRIKETHROUGH:
text.setStrikethrough(true);
break;
case UNDERLINED:
text.setUnderline(true);
break;
default:
break;
}
}
text.setStyle(textstyle);
flow.getChildren().add(text);
}
System.out.println(flow.getChildren());
return flow;
}
// In message add method
public void handle() {
if(packet.getType().equals(MessageType.NOTIFICATION)) return;
Message msg = packet.getMessage();
System.out.println(msg.toString());
TextFlow flow = MessageUtils.getTextFlow(msg.getExtra());
Platform.runLater(() -> {
MainController.getInstance().getLogsListView().getItems().add(flow);
});
}
I try replace Text to Label in TextFlow and it works!
Thanks for answers.
See converter's code below. Other code above I don't edit.
TextFlow flow = new TextFlow();
for(Message msg : list) {
Label text = new Label(msg.getFullText());
MessageStyle style = msg.getStyle();
ChatColor color = style.getColor();
String textstyle = "";
if(!(color.equals(ChatColor.NONE) || color.equals(ChatColor.NONE)))
textstyle += "-fx-text-fill: #" + TextColor.valueOf(color.name()).getHex() + ";";
System.out.println(textstyle);
for(ChatFormat f : style.getFormats()) {
System.out.println(f.toString());
switch (f) {
case BOLD:
if(!textstyle.equals("")) textstyle += " ";
textstyle += "-fx-font-weight: bold;";
break;
case ITALIC:
if(!textstyle.equals("")) textstyle += " ";
textstyle += "-fx-font-style: italic;";
break;
case STRIKETHROUGH:
if(!textstyle.equals("")) textstyle += " ";
textstyle += "-fx-strikethrough: true;";
break;
case UNDERLINED:
text.setUnderline(true);
break;
default:
break;
}
}
text.setStyle(textstyle);
flow.getChildren().add(text);
}
return flow;
}
I have a method that adds a label with some text to an existing xaml StackLayout.
The method is called from a couple of places, an event fired by xaml ListView and an NFC tag read. In both scenarios, the method is hit in the code-behind.
The methods both call another method that creates the label and adds it on screen. The one that originates from the ListView event works fine but the one from the NFC tag does nothing. It passes over each row of code without causing an exception but does not add anything to the screen. I can see after this that the child count of the StackLayout is 1 and remains as 1 if you do it again.
The NFC method:
public async void HandleNFC(string convertedtag)
{
int result = 0;
try
{
var mp = (MainPage)App.Current.MainPage;
Label sl1 = mp.CurrentPage.FindByName<Label>("timeLabel");
}
catch (Exception e)
{ }
Label sl = timeLabel;
string time = sl.Text;
PeopleLocationsForUserRoot peoplelocationforuser = await WebDataAccess.GetPeopleLocationForUser(UserInfoRepository.GetUserName(), _locationID);
DateTime dt = Convert.ToDateTime(time);
long timeticks = (long)((dt.ToUniversalTime().Ticks - DatetimeMinTimeTicks) / 10000);
getServerTime();
string name = "";
try
{
foreach (var person in peoplelocationforuser.locationPeople)
{
if (person.TATokenValue == convertedtag)
{
var action = await DisplayActionSheet(person.FirstName + " " + person.LastName, "Cancel", null, "IN", "OUT");
string act = action;
string formattedact = act;
int swipedirection = 0;
name = person.FirstName + " " + person.LastName;
if (act == "IN")
{
formattedact = "in";
swipedirection = 1;
}
if (act == "OUT")
{
formattedact = "out";
swipedirection = 0;
}
if (act != "Cancel")
{
result = SwipeRepository.ClockUserInOut(person.EB_Counter, _locationID, swipedirection, dt, timeticks, 1, UserInfoRepository.GetLatt(), UserInfoRepository.GetLongi());
addToReadout(name, time, formattedact);
}
}
}
if (name == "")
{
await DisplayAlert("Tag Error", "Tag not recognised", "cancel");
}
}
catch (Exception ex)
{
ErrorRepository.InsertError(ex.ToString());
}
await WebDataAccess.SaveSwipesToCloud();
}
The 'addToReadOut' method that it calls:
public void addToReadout(string name, string time, string inout)
{
try
{
Label label1 = new Label { Text = name + " Successfully clocked " + inout + " # " + time, TextColor = Color.Black };
try
{
readOut.Children.Add(label1);
StackLayout sl = this.FindByName<StackLayout>("readOut");
sl.Children.Add(label1);
sl.Focus();
timeLabel.Text = "test";
}
catch (Exception e)
{ }
// StackLayout sl = mp.CurrentPage.FindByName<StackLayout>("readOut");
if (readOut.Children.Count() < 6)
{
readOut.Children.Add(label1);
readOut.Children.Count();
}
else
{
readOut.Children.RemoveAt(0);
readOut.Children.Add(label1);
readOut.Children.Count();
}
}
catch (Exception ex)
{
ErrorRepository.InsertError(ex.ToString());
}
}
You can see that I have also tried to modify the object called 'timelabel' but does also does not change on screen.
The must be something different happening following the NFC event which is causing an issue here but I can't find what's causing it.
You NFC event is firing on a background thread; your UI updates need to happen on the UI thread
Device.BeingInvokeOnMainThread( () => {
// UI Code goes here
});
I am validating the input of my text field, which is of TextEdit type, using the Validating event. But the error icon is being displayed outside of the text field (second pic) rather than within it (first pic).
I've tried ErrorIconAlignment and it doesn't work. The icon is still being displayed outside of the text. Are there any other ways to have it displayed within the text field?
Thanks.
there is not a property allowing that.
but you can do this with the following code:
I created 2 buttons, 1 setErrorButton for set error an 2nd button for clear error with the SetError method, unwanted method CreatePictureEdit
private void setErrorButton_Click(object sender, EventArgs e)
{
SetError(textEdit1, "Error1");
textEdit1.Properties.MaskBoxPadding = new Padding(12, 0, 0, 0); //to put the cursor after the error image
}
private void clearErrorButto_Click(object sender, EventArgs e)
{
SetError(textEdit1, "");
textEdit1.Properties.MaskBoxPadding = new Padding(0, 0, 0, 0);
}
public static void SetError(Control ctrl, string errorText)
{
Form f = ctrl.FindForm();
if (errorText == string.Empty)
{
if (ctrl.Tag != null && ctrl.Tag is PictureEdit)
{
f.Controls.Remove(ctrl.Tag as PictureEdit);
return;
}
else
return;
}
PictureEdit edit = CreatePictureEdit(ctrl, errorText);
f.Controls.Add(edit);
ctrl.Tag = edit;
edit.BringToFront();
}
private static PictureEdit CreatePictureEdit(Control ctrl, string errorText)
{
PictureEdit edit = new PictureEdit();
Image image = BaseEdit.DefaultErrorIcon;
edit.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
edit.BackColor = Color.Transparent;
edit.Image = image;
edit.ToolTip = errorText;
edit.ToolTipIconType = DevExpress.Utils.ToolTipIconType.Error;
edit.Properties.SizeMode = DevExpress.XtraEditors.Controls.PictureSizeMode.Squeeze;
edit.Location = new Point(ctrl.Bounds.Left + 3, ctrl.Bounds.Y + 1);
edit.Size = new Size(image.Width, ctrl.Bounds.Height - 2);
edit.BackColor = Color.White;
return edit;
}
you can change the location property values and size of the image if the icon is not adjusted properly on the TextEdit
I dont know what I'am doing wrong with adding CSS style to node.
I have a main application window. Then I click menu item and another modal window opens as below(ModalWindow extends Stage):
FXMLLoader loader = new FXMLLoader(getClass().getResource(CONSTANTS.ROOT_USER_EDIT.string));
BorderPane editPane;
try {
editPane = new BorderPane(loader.load());
ModalWindow editWindow = new ModalWindow(Main.mainStage, editPane, "Edit user");
//its new stage with new scene, so we need to load this file again
editWindow.getScene().getStylesheets().add(getClass().getResource(CONSTANTS.CSS_PATH.string).toExternalForm());
UserData userData = (UserData)usersTable.getSelectionModel().getSelectedItem();
UserEditWindowController userEditWindowController = loader.getController();
userEditWindowController.fillWithData(userData);
editWindow.initModality(Modality.APPLICATION_MODAL);
editWindow.showAndWait();
} catch (IOException exception) {
ExceptionDialog exceptionDialog = new ExceptionDialog("Couldn't load UserEditWindow",exception);
exceptionDialog.showAndWait();
}
this CSS file is added:
#greenInfoTip {
-fx-graphic-text-gap: 20;
-fx-font-size: 44.0px ;
-fx-background: green;
-fx-background-color: rgb(128,255,128);
}
And I try to do this in root controller class:
infoTip.setId("greenInfoTip");
but with no effect. Is there something I'm doing wrong?
EDIT ItachiUchiha here is precisely what it looks like:
method is inside UserEditWindowController class:
#FXML
private void buttSaveAction(ActionEvent event){
//check if login and password doesn't contain spaces and is 4-16 characters long
String login = textFLogin.getText();
String password = textFPassword.getText();
boolean hasLoginWhiteSpace = isContainingWhiteSpace(login);
boolean hasPasswordWhiteSpace = isContainingWhiteSpace(password);
boolean isLoginMoreThan3 = (login.length() > 3)? true : false;
boolean isLoginLessThan17 = (login.length() < 17)? true : false;
boolean isPasswordMoreThan3 = (password.length() > 3)? true : false;
boolean isPasswordLessThan17 = (password.length() < 17)? true : false;
InfoTip infoTip = new InfoTip();
if( hasLoginWhiteSpace == false){
if( hasPasswordWhiteSpace == false ){
if( isLoginMoreThan3 == true && isLoginLessThan17 == true){
if( isPasswordMoreThan3 == true && isPasswordLessThan17 == true ){
//========login and password are correct
String query = "UPDATE users SET login = ?, password = ? WHERE employee_id = ?;";
try( Connection connection = Main.dataSource.getConnection() ){
try( PreparedStatement preparedStatement = connection.prepareStatement(query) ){
preparedStatement.setString(1, login);
preparedStatement.setString(2, password);
preparedStatement.setInt(3, currentUser.getiD());
preparedStatement.executeUpdate();
currentUser.setLogin(login);
currentUser.setPassword(password);
infoTip.getInfoTip().setId("greenInfoTip");
infoTip.showTip((Button)event.getSource(), "Saved");
}
}catch(Exception exception){
ExceptionDialog exceptionDialog = new ExceptionDialog("Error while loading data from database",exception);
exceptionDialog.showAndWait();
};
}else{ //password has less than 4 or more than 16 characters
infoTip.showTip(textFPassword, "no more than 16 and no less than 4 characters!");
}
}else{ //login has less than 4 or more than 16 characters
infoTip.showTip(textFLogin, "no more than 16 and no less than 4 characters!");
}
}else{ //password has white space
infoTip.showTip(textFPassword, "no spaces!");
}
}else{ //login has white space
infoTip.showTip(textFLogin, "no spaces!");
}
}
public class InfoTip {
private Tooltip infoTip;
public InfoTip(){
infoTip = new Tooltip();
}
private static Point2D getNodePos(Node node){ //getting node coordination on screen
Scene nodeScene = node.getScene();
final Point2D windowPos = new Point2D(nodeScene.getWindow().getX(), nodeScene.getWindow().getY());
final Point2D scenePos = new Point2D(nodeScene.getX(), nodeScene.getY());
final Point2D nodePos = node.localToScene(0.0, 0.0);
final Point2D nodePosOnScreen = new Point2D(windowPos.getX() + scenePos.getX() + nodePos.getX(),
windowPos.getY() + scenePos.getY() + nodePos.getY());
return nodePosOnScreen;
}
public void showTip(Node node, String text){
Point2D nodePosOnScreen = getNodePos(node);
infoTip = new Tooltip(text);
infoTip.setFont(new Font(15));
infoTip.setOpacity(0.9);
infoTip.setAutoFix(true);
infoTip.setAutoHide(true);
infoTip.show(node, nodePosOnScreen.getX()-30, nodePosOnScreen.getY() - 40);
}
public Tooltip getInfoTip(){
return infoTip;
}
}
The issue is with
infoTip = new Tooltip(text);
inside howTip(Node node, String text).
You are over-writing the old tooltip with id with a new object. Try using
infoTip.setText(text);