I have a TextArea, and a associated CheckBox to disable and enable the TextArea (setEnabled(Boolean)), which is used to decide if it is a required field or not.
My problem is that Wicket does not keep the text in the TextArea when it is disabled (setEnabled(false)). It clears the input.
How do I keep the value in the TextArea before setEnabled is called on it? I need to update the Model serverside,
Can I do a AJAX request to update it? I haven't found any example.
checkBox.add(new AjaxFormComponentUpdatingBehavior("onchange") {
#Override
protected void onUpdate(AjaxRequestTarget target) {
if (textField.isEnabled()) {
textField.inputChanged();
// Update text input in PropertyModel….
}
textField.setEnabled(false); // This change in state does not include text that have been typed in
tekstFelt.setRequired(false);
target.add(textField);
}
});
You must add an AjaxFormComponentUpdatingBehavior for the blur event to the TextArea so that when you type in the textarea and leave the textarea (lose focus = blur) what you typed will be persisted by the model. Sample code:
private TextArea textarea() {
TextArea textarea = new TextArea("textarea", new PropertyModel<String>(this, "value")){
#Override
protected void onConfigure() {
setEnabled(condition());
}
};
textarea.setOutputMarkupId(true);
textarea.add(new AjaxFormComponentUpdatingBehavior("blur") {
#Override
protected void onUpdate(AjaxRequestTarget target) {
}
});
return textarea;
}
I also recommend that wheter the textarea is enabled or not you should set in onConfigure() of the textarea. When you want to updated the textarea you just add it to the AjaxRequestTarget and the textarea knows if it should be enabled. This is a best practice and is not directly correlated to your question.
Related
There is input text field and submit button. I would like to show button text field not empty and otherwise button should be not visible.
TextArea<String> textMessageField = new TextArea<>("textMessage", textMessageModel);
Button submitBtn = new Button("saveReminderButton") {
#Override
protected void onConfigure() {
super.onConfigure();
String text = textMessageField.getModelObject();
setVisible(text != null && !text.isEmpty());
}
};
textMessageField.add(new OnChangeAjaxBehavior() {
#Override
protected void onUpdate(AjaxRequestTarget target) {
target.add(submitBtn);
}
});
submitBtn.setOutputMarkupId(true);
I'm trying to use setVisible method in onConfigure but it doesnt work. I tried to use instead setEnabled and it was working but I need the same functionality with hide/show button
Since you make the button invisible you need to use submitBtn.setOutputMarkupPlaceholderTag(true); instead of submitBtn.setOutputMarkupId(true);
This is important because without setOutputMarkupPlaceholderTag(true) Wicket Wicket will render nothing for this component. With setOutputMarkupPlaceholderTag(true) it will render <htmlElement id="someId"></htmlElement>. This way Wicket Ajax could find it in the DOM and replace it with the HTML of the visible one.
Copy text into your clipboard, right click text field and press "paste", is there a way how to listen when paste was clicked? Or rather that input text in the field changed after something was pasted this way. Because these do not work in this particular case:
setOnKeyReleased()
setOnInputMethodTextChanged()
The "paste" functionality is implemented in the TextInputControl superclass of TextField in public void paste(). So, while it's not really an event-driven or MVC approach, you can react to a "paste" action (whether it's invoked by mouse or keyboard shortcut, typically ctrl-V) by overriding this method:
TextField tf = new TextField() {
#Override
public void paste() {
super.paste();
System.out.println("text pasted in");
}
}
you could just listen to text property changes.
example with a search text field:
tf_search.textProperty().addListener((observableValue, oldValue, newValue) -> {
onSearch();
});
The other approach would be to override the appropriate method using Clipboard.
TextField tf = new TextField() {
#Override
public void paste() {
Clipboard clipboard = Clipboard.getSystemClipboard();
if (clipboard.hasString()) {
replaceSelection(clipboard.getString());
}
}
};
I have a tableViewer where I can edit 1 column. Everytime the cellEditor from this column gains focus I want all the text that is displayed to be selected. In a normal SWT text control, we would just do text.selectAll(); , so I've set this listener for the the cellEditor inside the column EditingSupport class:
editor.getControl().addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
Text text = (Text) editor.getControl();
text.selectAll();
}
});
I know I can cast the cellEditor control to a Text input because I've tested it with a normal setText(); and it Works! However, the selectAll(); is not working, how can I fix this?
SOLUTION
I found the error, the code in my question above works perfectly, the reason I wasn't able to see the selectAll(); doing something is in this method:
#Override
protected Object getValue(Object element) {
String valor = MathUTILS.getBigDecimalFormatted(((ColaboradoresDespesasDocumentosLinhas) element).getValor(), PatternVARS.PATTERN_BIGDECIMAL_MILLION);
Text text = InterfaceFormatUTILS.getControlNumberFormat(editor, PatternVARS.PATTERN_BIGDECIMAL_BILLION);
return valor;
}
This is also a method from the EditingSupport class, and for some reason formatting the text control (Text text = InterfaceFormatUTILS.getControlNumberFormat(editor, PatternVARS.PATTERN_BIGDECIMAL_BILLION);) deselects all the text. Also, doing the selectAll(); in this method doesn't work..
I have already seen : How to set AUTO-SCROLLING of JTextArea in Java GUI?
blackArea = new JTextArea();
blackArea.setFont(new Font("Tahoma", Font.BOLD, 11));
blackArea.setText("Loggend on Administrator...\n" +date);
blackArea.setForeground(Color.RED);
blackArea.setBackground(Color.BLACK);
DefaultCaret caret = (DefaultCaret)blackArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
blackArea.setCaretPosition(blackArea.getDocument().getLength());
scrollPane.setViewportView(blackArea);
This works well. When update to JTextArea, the scroll moved to bottom automatically so I could see the refresh data. But the problem is, when I click the any space in JTextArea, the auto-scrolling is stopped. No more auto scroll works. How to fix it?
SUPPLEMENT : I added text to blackArea calling GUI.blackArea.append("bla bla bla"); GUI is class name where above code included. Thanks for #hovercraft-full-of-eels
Check out Smart Scrolling. It is an improvement over the other scrolling answer.
It the scrollpane is at the bottom when the append occurs it will continue to keep the scrollpane at the bottom. However, if the user has move the viewport from the bottom then the append will not automatically scroll to the bottom.
You don't show where you are adding or appending text to the JTextArea, and this is critical since the changing of the caret position should occur there.
Edit
You state:
Sorry, I just append text in other class, just calling GUI.blackArea.append("bla bla bla"); Should I use SwingUtilities.invokeLater?
I know you've got a decent answer from Rob Camick, a true Swing guru, but I also have to add that you really shouldn't expose your class's fields that way (and hopefully none of your components are declared static as your code suggests that they may be). Instead expose public methods that allow controlled ability to change the state of your fields. For instance your GUI class could have a public method like so
public void blackAreaAppend(String text) {
blackArea.append(text);
// code here to advance cursor
}
Or if this method is always called off of the EDT:
public void blackAreaAppend(String text) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
blackArea.append(text);
// code here to advance cursor
}
});
}
Or if you're just not sure:
public void blackAreaAppend(String text) {
if (SwingUtilities.isEventDispatchThread()) {
blackArea.append(text);
// code here to advance cursor
} else {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
blackArea.append(text);
// code here to advance cursor
}
});
}
}
I solved this problem. this is the problem of view-point. when I click any space on JTextarea, the location of caret is changed, so view-point is changed too. Following my code, there is no update with view point.
So, I made a method :
public static void addLog(final String log){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
GUI.blackArea.append(log);
GUI.blackArea.setCaretPosition(GUI.blackArea.getDocument().getLength());
}
});
}
I changed blackArea.append("...") to `addLog("...). and I got out of this problem, However, remember that you can't fix caret positon while updating.
I have a form and there is a TextField. I added button to a form, different than the default submit. I want to use Ajaxformcomponentupdatingbehavior to get the value from the TextField after clicking the button next to the TextField.
My code looks like:
private String string;
...
public ..() {
Form form = new Form("form") {
#Override
protected void onSubmit() {
//some code
};
add(form);
TextField textField = new TextField("string", new PropertyModel<String>(this,"string"));
textField.setOutputMarkupId(true);
form.add(textField);
Button button = new Button("evalButton");
form.add(button);
button.add(new AjaxFormComponentUpdatingBehavior("onclick") {
#Override
protected void onUpdate(AjaxRequestTarget target) {
System.out.print(textField.getValue());
}
});
the value of the TextField is null, after clicking the button for the second time, I get the right value. How could I get the value of the TextField after one button click?
AjaxFormComponentUpdatingBehavior doesn't do quite what you think. The behaviour is actually applied to the TextField, not to the button. Your code is updating the model of the button rather than the text. See this previous question for an example.
I've done this before for a postcode lookup button in an address form. I used an `IndicatingAjaxButton' to push the entire form, and I disabled default form processing. I then grabbed the text input directly, pushed it through my validator which standardised the formatting, then processed:
final IndicatingAjaxButton lookup = new IndicatingAjaxButton("lookup", form) {
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
String code = postcode.getInput();
code = (new PostcodeValidator()).convertToObject(code,
getLocale());
... Postcode lookup here
target.add(ContactDetailsPanel.this);
}
#Override
protected void onError(AjaxRequestTarget target, Form<?> form) {
}
};
lookup.setDefaultFormProcessing(false);
add(lookup);