I have a TextField where I have added an AjaxFormComponentUpdatingBehavior to get the current value when user write some string.
filterByObject = new TextField<String>("filterByObject", true, new PropertyModel<String>(searchParams, "objectFilter"));
AjaxFormComponentUpdatingBehavior changeFilterBinded = new AjaxFormComponentUpdatingBehavior ("onkeyup") {
#Override
protected void onUpdate(AjaxRequestTarget target) {
target.addComponent(componentToUpdate);
}
};
filterByObject.add(changeFilterBinded);
When I put some chars inside textfield, onUpdate method is correctly called and my component, based on the current state of searchParams, changes correctly.
Unfortunally when I use Backspace to cancel what I have inserted, the onUpdate is not called.
I tried changing event (onkeypress, onkeydown, onchange etc...) but it doesn't work. Only onChange works but I have to change focus to another component.
How can I save the day?
Is the input in the field invalid (according to setRequired or IValidators added to the field) as a result of pressing the backspace key? If it is, the onError method will be called instead of onUpdate, because user input will be invalid and therefore will not reach the ModelObject of the component with the AjaxFormComponentUpdatingBehavior.
AjaxFormComponentUpdatingBehavior changeFilterBinded =
new AjaxFormComponentUpdatingBehavior ("onkeyup") {
#Override
protected void onUpdate(AjaxRequestTarget target) {
// Here the Component's model object has already been updated
target.addComponent(componentToUpdate);
}
#Override
protected void onError(AjaxRequestTarget target, RuntimeException e){
// Here the Component's model object will remain unchanged,
// so that it doesn't hold invalid input
}
};
Remember that any IFormValidator involving the ajax-ified component will not execute automatically, so you might be interested in checking the input for yourself manually before updating model objects if it's the case. You can tell AjaxFormComponentBehavior not to update model objects automatically by overriding getUpdateModel(). Then, in the onUpdate method, get the component's new input by means of getConvertedInput().
As a side note, onkeyup should be getting fired when pressing the backspace key. At least it does in this fiddle, and onchange is generally triggered on an <input type="text"> when focusing out of it.
Also, HTML5 introduces the oninput event handler, which may better suit your needs. It will get fired even when copying/pasting in the text field. See the following link for more information: Using the oninput event handler with onkeyup/onkeydown as its fallback.
Related
I have a combo box and I set the default value for this combo box at the initialisation of the node. However, once there is some data retrieved from a database I want to update this default value to something else.
initialise() {
businessDateComboBox.setItems(config.retrievedPositionsData().getDistinctBusinssDate());
businessDateComboBox.setValue(config.retrievedPositionsData().getCurrentBusinessDate().toString());
}
The setItems is an ObservableList and the setValue is an ObservableList to but ive converted it to string.
Now I use a separate thread to retrieve items from database.
public void readPositionsFromDataBase() throws Exception {
Task<Integer> task = new Task<Integer>() {
#Override protected Integer call() throws Exception {
config.positionViewPersister().readDataFromDataBase(null,null);
return 0;
}
};
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
config.retrievedPositionsData().setCurrentBusinessDate("56")
}
Once this finishes I want to update the User Interface with the latest value retrieved for default combo box value. I do this by reloading the FXML and the corresponding controller of the FXML which consists of the initialise method - currently the initialise method is run again but the user interface does not get updated with the latest value. Does anyone know why?
The default value in combo box in user interface should now be 56 as ive set it. When I print businessDateComboBox.getValue() it gives 56 it just isn't updating the User Interface.
Is there any equivalent of the swing redraw or something?
businessDateComboBox.setValue is meant for the edit component of an editable ComboBox. I guess yours is not, so the right way to go should via the SelectionModel:
businessDateComboBox.getSelectionModel().select(...)
I have this method that contains a MouseEvent. How do I return the idu variable?
it is like a method in a method or how to call it and I can't figure out how top return the idu variable.
public int getId() {
int idu;
table.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 1) {
JTable target = (JTable)e.getSource();
int row = target.getSelectedRow();
Object record = data[row][0];
idu = (Integer) record;
}
}
});
return idu;
}
In nearly all cases the 'listener' pattern involves registering listeners with methods that do not have return values. In general a return value from a listener is meaningless because it's being returned to caller that has no context about what to do with it.
It seems to me you have misunderstood a few things in the code you have posted:
1. it makes little sense to register a listener in a 'getter' method. The listener needs to be registered once, generally in the class's constructor
2. registering a listener doesn't do anything on its own: it just tells the handler to call your method when an event occurs (in this case clicking a mouse).
3. unless you are reusing the listener in several places (which you are not in this code fragement because it's an anonymous class) then you don't need to get the event source - you should already have it as a member field in the class.
So the answer in your case is that your JTable should be a member field of your class. Then the getId method need only return the selected row of the table. There is no need to register a mouse listener at all as the selected row is available in JTable without any additional work.
Think about the following question:
When do expect to have the idu value ready for use - when the method getId() finished running, or when the user clicked the mouse button over the table?
What your code actually do is to register an event listener, kind of like setting an alarm or scheduling a task for later, and then going to sleep, or back to do whatever other task you need to do now.
The value of idu doesn't neccessarily exist when you exit the getId() method, because the code in the mouseClicked() method didn't neccessarily executed yet. It will only execute when the event actually happen.
I am doing an homework in JavaFX2.1 and I have a problem with the setOnKeyPressed method.
My programs simulates a piano, so it does a sound every time I click on a button: 'Q' is 'do', 'W' is 're' and so on... I also have (for now) a mouse input, which will be disabled later since I can't play several notes at once with it...
My problem: if I hold down a key (on the keyboard of course, not with the mouse) its associated event will be triggered in a loop...
I did several tests and noticed that only the setOnKeyPressed is triggered, not the setOnKeyReleased.
I did some workarounds but they are not doing what I expect:
adding a boolean value to know if the key has been released disables the possibility of pushing on multiple keys at once.
turning off the volume after the sound has been played (and putting it back to its value when the key is released) seems to work, also for multiple keys, BUT the duration of the sound is considerably shorter compared to when I hold down the mouse on the same key.
Any suggestions?
You can't disable multiple events as it's system behavior. The best solution for you would be to improve boolean flag approach to store flag for each key. E.g. next way:
final Set<String> pressedKeys = new HashSet<String>();
keyboard.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
String note = t.getText();
if (!pressedKeys.contains(note)) {
// you may need to introduce synchronization here
pressedKeys.add(note);
playNote(note);
}
}
});
keyboard.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
pressedKeys.remove(t.getText());
}
});
I need to be able to detect if a certain key (e.g. CTRL) is pressed during a specific operation of mine. I don't have access to a key listener, nor to a mouse event. What I'm hoping is that there will be some class that has a method like "boolean isKeyPressed(keycode)".
Is anyone aware of a method like this in java?
For a bit of background, I am trying to override the default drag & drop behaviour for a component. By default, according to the javadocs for DropTargetDragEvent, if no key modifier is pressed, then the it looks in the component's supported actions list for a move, then a copy & then a link and stops after finding the first one.
In my application, we support both copy & link. As per the javadoc, without the CTRL key pressed, the default action is copy. We want the user to be able to specify the default action (allowing them to set their most commonly used) and then force a specific one using the modifier keys.
If I can detect the key pressed state then I can force this to happen but I can't see any other way of changing the default action.
Thanks in advance, Brian
The MouseEvent.getModifiers() method will return a bitmap of modifier keys that are pressed at the time the MouseEvent was generated. Or, you could use MouseEvent.isControlDown() to check specifically the CTRL key.
This is a possibly dirty way to go about it. But this allows you to 'record' key events and then query them.
//register this somewhere in the startup of your application
KeyboardFocusManager mgr = KeyboardFocusManager.getCurrentKeyboardFocusManager();
mgr.addKeyEventDispatcher(KeyEventRecorder.getInstance());
//then can query events later
KeyEvent keyEvt = KeyEventRecorder.getLastEvent();
if( keyEvt != null && keyEvt.getKeyCode() == KeyEvent.VK_CONTROL && keyEvt.getID() == KeyEvent.KEY_PRESSED )
//do something..
private class KeyEventRecorder implements KeyEventDispatcher
{
private static KeyEvent lastEvent;
private static KeyEventRecorder myInstance;
private KeyEventRecorder()
{
super();
}
public static synchronized KeyEventRecorder getInstance()
{
if( myInstance == null )
myInstance = new KeyEventRecorder();
return myInstance;
}
/**
* retrieve the last KeyEvent dispatched to this KeyEventDispatcher
*/
public static KeyEvent getLastEvent()
{
return lastEvent;
}//method
#Override
public boolean dispatchKeyEvent(KeyEvent e)
{
lastEvent = e;
//return false to let KeyboardFocusManager redistribute the event elsewhere
return false;
}//method
}//class
Even if there was such a method, what do you want to do with it? Call it in an endless loop in the hope it returns true at some point? I think an event-based / listener-based mechanism suits much better in this case.
I think you are going about this the wrong way. What you want to do is change the action when the drag is initiated, not when it is dropped. There are ways to change what the action is on initiation, including interrogating the user preferences in the "no modifiers" case. It's possible that changing the way the DropTargetDragEvent is called.
I know that when creating buttons, like next and previous, that the code can be somewhat long to get those buttons to function.
My professor gave us this example to create the next button:
private void jbtnNext_Click() {
JOptionPane.showMessageDialog(null, "Next" ,"Button Pressed",
JOptionPane.INFORMATION_MESSAGE);
try {
if (rset.next()) {
fillTextFields(false);
}else{
//Display result in a dialog box
JOptionPane.showMessageDialog(null, "Not found");
}
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
Though, I do not really understand how that short and simple if statement is what makes the next button function. I see that the fillTextFields(false) uses a boolean value and that you need to initialize that boolean value in the beginning of the code I believe. I had put private fillTextFields boolean = false; but this does not seem to be right...
I'm just hoping someone could explain it better. Thanks :)
Well, fillTextFields(true); is a function call and when you pass in a true/false flag it does some things (you have to see the code inside the function in order to find out exactly what it does).
The field declaration private fillTextFields boolean = false; is invalid, you're supposed to provide the type before the name, e.g.: private boolean fillTextFields = false;. Aside from the invalid syntax that flag really doesn't do anything, especially if you're not using it anywhere.
I don't understand what else you expect to see in the jbtnNext_Click() method... when you declare your button and it gets clicked on the UI, then this method gets invoked. It doesn't make the button work, the button works even when you have nothing in the jbtnNext_Click() method. For example:
private void jbtnNext_Click() {
// The button will still work, but it simply won't do anything
}
Getting a button to function depends on what you view as a functioning button. What is supposed to happen when you click next/previous?
Update:
I thought that I needed the boolean
declaration to make the
"fillTextFields(false)" work.
Was the fillTextFields method given to you somewhere? If it was, then you don't need to declare anything, much less a variable. If it's already provided, then you just call the method, that's all. If it's not provided then you need to declare it:
private void fillTextFields(bool shouldFill)
{
if(shouldFill)
{
// fill the text fields
}
// possibly have an else statement if you need to do something else here
}
Otherwise what you see in that function is all you need to do in order to go to the next record in the database.
I think that the code provided is a bit short to provide a good explanation, posting the code for fillTextFields would be of more help.
What I can guess that the program is doing is that it is retrieving some data from a database. The next button allows the program to iterate through the items that have been returned.
Once that the next button is pressed, a message box is shown to let you "know" that the button has indeed been pressed.
rset.next returns true of there is another element in the list (retrieved from the database), or false if there isn't.
If it returns true, you are calling the fillTextFields methods, which I guess displays the data on screen (even though without the code I can just speculate). If there isn't anything left, a message box displaying "Not Found" is shown.
With regards to your question about
private fillTextFields boolean = false;
fillTextFields is a method, and you cannot assign values to methods. Also, in Java, when declaring both methods and variables, the type is written before the name, such as
private int number;
public float myMethod() { }
The next button won't do anything unless you register an action with the button. What I mean is, wherever your next button is defined looks something like this:
private JButton nextButton = new JButton("Next");
This creates a button that has the label, 'Next'. There might be some additional code for positioning the button. In order for that button to do anything when it is clicked, it needs to have an Action set on it, or it has to have an ActionListener added to it. Many times, the class that is creating the button implements ActionListener and has a method to respond to the click, something like:
nextButton.addActionListener(this);
...
...
...
public void actionPerformed(ActionEvent e) {
// some method implementation
}
The actionPerformed method is called when the button is clicked, AS LONG AS you've registered the action listener on the button. Is anything like this present in the code from your professor?