How to determine if Mnemonic/KeyCombination for a control is triggered? - java

I'd like to know how can I determine if the KeyCombination (constructed via Mnemonic) for a control is triggered. Or for simplicity's sake, a handler method for Mnemonics?
Basically, I'm working with a custom control which extends from Labeled and from its Behavior class, I want to perform some extra actions when the assigned Mnemonic is triggered.
EDIT
So after a little bit digging, I came up with an idea to simply listen to a KeyEvent from the Scene (but take note that this is JUST AN IDEA. Either way, I'll figure out the rest later on). Here's how:
public CustomLabeledBehavior(CustomLabeled control) {
super(control, ...);
/* IMPORTANT PART */
// Assume that mnemonicParsing is set to true
TextBinding tb = new TextBinding(control.getText());
KeyCombination kc = tb.getMnemonicKeyCombination();
control.getScene().addEventFilter(KeyEvent.KEY_PRESSED, e -> {
if (kc.match(e)) {
System.out.println("MATCHED!");
}
});
}

UPDATE
To make this answer more useful than it used to be, I'll show you the usage of the method I'm currently using to determine if the KeyCombination is triggered. So I'll try to explain every single detail if I can.
We are only focusing on adding a Mnemonic, using the MnemonicParsing property of a custom control. And we will call this custom control as CustomLabeled since based on the question, it extends from the Labeled class, hence the name is based to it. Then we will work things inside its Skin class called, CustomLabeledSkin.
#1 Initializing the control:
<!-- Assuming that this FXML is already set and is attached to a Scene -->
<CustomLabeled text="_Hello World!" mnemonicParsing="true"/>
#2 Setting up our MnemonicHandler:
/* These two variables are initialized from the Constructor. */
private KeyCombination kb; // The combination of keys basically, ALT + Shortcut key
private String shortcut; // The shortcut key itself basically, a Letter key
private boolean altDown = false; // Indicator if the user press ALT key
/**
* This handler is a convenience variable to easily attach
* and detach to the Scene's event handlers. This is the
* whole idea to determine whether the KeyCombination is
* triggered.
*/
private EventHandler<KeyEvent> mnemonicHandler = new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
// The KeyCombination, basically, the ALT + Shortcut key.
if (kb.match(event) {
// TODO: Execute command here.
event.consume(); // Prevent from further propagation.
return; // Make sure that the rest won't be executed.
}
// While these two functions are for separate event.
// Example, pressing ALT first before the Shortcut key.
if (event.isAltDown()) altDown = !altDown;
if (altDown && event.getCode() == KeyCode.getKeyCode(shortcut)) {
// TODO: Execute command here.
event.consume();
}
}
}
#3 Initialize our Skin class:
/**
* Constructor
*/
public CustomLabeledSkin(CustomLabeled control) {
// Since this is just an example/testing, we will only assume
// that MnemonicParsing is enabled and a valid Mnemonic is
// registered. So if you want to validate a mnemonic, you
// might want to do it here.
TextBinding tb = new TextBinding(control.getText());
kc = tb.getMnemonicKeyCombination();
shortcut = tb.getMnemonic();
// Then we can just filter for a KEY_PRESS from the Scene, then
// everything else will be handled by our MnemonicHandler.
control.getScene().addEventFilter(KeyEvent.KEY_PRESSED, mnemonicHandler);
}
NOTE: The TextBinding class is not part of the public API, it is used by the Labeled node to handle Mnemonics.
Further more, you can create a method to detach the MnemonicHandler if there's no currently Mnemonics assigned (E.g previously there's a mnemonic, then code was changed...).

Related

Disable dragging of selected object in Piccolo2d?

I know Piccolo2d is an old project, but I have a couple of questions.
1) Is it possible to disable dragging a selected object? For this particular use case, I only want to select an object, not move or delete it. I know I can disable deletion using:
this.selector.setDeleteKeyActive(false);
But I don't see an option to disable dragging. Is the only option to override the drag functionality in the event handler?
2) Is there no way to have the selection handler active at the same time as the pan/zoom handlers? It seems a bit archaic to disable pan/zoom when you want to support object picking. Or do I have to create my own handlers?
My current code is:
...
this.pluginContext.getCanvas().setPanEventHandler(null);
this.selector = new PSelectionEventHandler(this.mapLayer.getNode(), this.mapLayer.getNode()) {
};
this.selector.setDeleteKeyActive(false);
this.pluginContext.getCanvas().addInputEventListener(this.selector);
PNotificationCenter.defaultCenter().addListener(this, "nodeSelected",
PSelectionEventHandler.SELECTION_CHANGED_NOTIFICATION, this.selector);
...
public void nodeSelected(final PNotification notification) {
logger.debug("Selection - " + this.selector.getSelection().toString());
}
In true developer tradition, I found an answer.
My pickable nodes are all grouped under individual grouping nodes. This lets me add an event listener on the grouping node, like this:
groupNode.addInputEventListener(new PBasicInputEventHandler() {
public void mouseReleased(final PInputEvent event) {
PNode node = event.getPickedNode();
if (node != null) {
onNodeSelected(node); // your logic here
}
}
});
The beauty of this is that the event contains the picked node that is grouped under that group node. Perfect! Also, you don't have to disable the pan/zoom handlers.
The only downside is that this doesn't give you the selection decorator around the node. Can't win 'em all!

Java Methods when working with Swing - It is possible to call event method in another event method in same class?

so I am new to java and using right now swing. I have an method (first method) that does some code when I type in specific jField and release key.
I also have jCheckBox, so when I tick or untick checkbox it does some action, this is second method.
So I want when I tick or untick checkbox make it call my first method and first method must do it's code. But it seems I have problem and I can't call this method fro some reason.
Part of first method:
private void bruttoTextFieldKeyReleased(java.awt.event.KeyEvent evt) {
//code
}
Second method trying to call first method:
private void pensionCheckBoxStateChanged(javax.swing.event.ChangeEventevt) {
bruttoTextFieldKeyReleased();
}
Those methods were created with this menu
And this is hint, but I am not sure what I need to do, it required some KeyEvent? I just want launch one method from another, not putting any value and not returning.
Error Hint
To expand a bit on Luvy's comment, and convert it into an answer using your code.
Right now, the first method takes a KeyEvent, and looks like this:
private void bruttoTextFieldKeyReleased(java.awt.event.KeyEvent evt) {
double salaryBrutto = Double.parseDouble(bruttoTextField.getText());
double taxPensRound;
if (pensionCheckBox.isSelected()) {
double taxPens = salaryBrutto * TAX_PENS;
//more code
Going by the screenshots, it looks like you most likely auto-created it from a GUI builder, and are not using the KeyEvent evt parameter. You aren't able to call this method without passing in a KeyEvent, which is why pensionCheckBoxStateChanged cannot call it.
Luvy's suggestion would be to create a new method out of the bruttoTextFieldKeyReleased button, so afterwords you would have two methods:
private void bruttoTextFieldKeyReleased(java.awt.event.KeyEvent evt) {
calculatePensionInformation();
//maybe do something with evt later on
}
and
private void calculatePensionInformation() {
double salaryBrutto = Double.parseDouble(bruttoTextField.getText());
double taxPensRound;
if (pensionCheckBox.isSelected()) {
double taxPens = salaryBrutto * TAX_PENS;
//more code
}
At this point, you could change your existing second method to be:
private void pensionCheckBoxStateChanged(javax.swing.event.ChangeEventevt) {
calculatePensionInformation();
}
And it would work as expected, since calculatePensionInformation requires no parameters, and you are passing in no parameters.

problems with returning a value java

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.

Java - Can we detect if a key is pressed without using a Listener?

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.

Simplest way of creating java next/previous buttons

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?

Categories

Resources