Pressing TAB key loses focus on widget - java

I am using a Table component in SWT. Whenever I edit a value in this table and press enter, this value is saved in the text component in this table.
But when I want to enter 2 words seperated with a TAB between them, then the editor loses focus and moves on to the next cell to edit(like pressing tab in a browser form). I don't want this to happen and let my users enter tabs between words without the focus getting lost. Anyone have an idea how to create this?
I allready tried using a keyListener, but it seems the tab event isn't even processed by this listener

You could add a TraverseListener to your textField.
text.addTraverseListener(new TraverseListener () {
public void keyTraversed(TraverseEvent e) {
switch (e.detail) {
case SWT.TRAVERSE_TAB_NEXT:
case SWT.TRAVERSE_TAB_PREVIOUS: {
e.doit = false;
}
}
}
});
Check out this example code snippet.

Related

Adding input filter to TextField blocks default handling of ESC key

Context: JDK 8 & JavaFX
I have a TextField control that is used in a dialog. It is the first edit control, so it gets the focus when the dialog opens. The dialog has a button configured as the cancel button (Button.setCancelButton(true))
With a plain TextField, if I hit ESC immediately after the dialog opens, the dialog is closed (as expected).
However, once I add a TextFormatter with input filter to the TextField, the ESC keypress appears to be being consumed by the input control and ESC no longer closes the dialog.
The TextFormatter only has an input filter (to restrict the input control to just digits), but the input filter does not get invoked on the ESC keypress - because the content of the field has not changed.
It's a fairly minor issue, but it's annoying not having consistent behaviour, and not being able to just hit ESC to dismiss the dialog. Any ideas on how to ensure that the ESC keypress is propagated/not consumed, so that it is handled by the dialog?
Edit:
My question appears to be a duplicate of this one: Escape from a Number TextField in a JavaFX dialog. Which of course I failed to find despite trawling through Google before posting... TLDR; the TextFormatter class fails to forward the ESC keypress event on.
I think the easiest approach is to avoid trying to “fix” the TextField and TextFormatter, and just add a key listener:
textField.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ESCAPE) {
dialog.setResult(ButtonType.CANCEL);
}
});
If the Dialog is not an Alert (or more precisely, is not a Dialog<ButtonType>), you can locate the button and activate it yourself:
textField.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ESCAPE) {
Button cancelButton = (Button)
dialog.getDialogPane().lookupButton(ButtonType.CANCEL);
cancelButton.fire();
}
});

How do I change the focus on buttons of JFace WizardPage?

I have implemented a JFace Wizard with 2 WizardPages.
By default, the first WizardPage has these 4 Buttons:
Back (disabled)
Next (focused)
Cancel
Finish (disabled)
Now I want to set the default focus on the Cancel Button. How do I do that?
Removing the focus and setting it to some Control of the page's content would also be ok.
I tried setting the focus to a Button in the content layout of the WizardPage, but this only sets me a second focus on the immediateButton. The focus on the Next button is still there, and the Next button reacts to pressing enter, which is what I want to avoid.
#Override
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible) {
immediateButton.setFocus();
}
}
How can I access the Dialog buttons and change their focus?
The Next button does not actually have focus, rather it is the Shell Default button.
The logic in WizardDialog makes either Next or Finish the default button and there does not seem to be a way to change this.
You may be able to override this by calling getShell().setDefaultButton(button) in your wizard page.
Update: Testing this you can do it in setVisible but you need to use Display.asyncExec to make the code run at the right time:
final Shell shell = getShell();
shell.getDisplay().asyncExec(() -> shell.setDefaultButton(immediateButton));
above is for Java 8, for Java 7 or earlier:
shell.getDisplay().asyncExec(new Runnable()
{
#Override
public void run()
{
shell.setDefaultButton(immediateButton);
}
});

Showing combo box when a specific selection occurs

I am coding a bookshop in Java and have a problem with when a new book is ordered I want the user to select whether it is a ebook or paper book. If it is an ebook I want another combo box to show on the page with called cboFormat. I have some code but it doesn't seem to work.
This is in the constructor.
if("Ebook".equals(cboBookType.getSelectedItem()))
{
cboFormat.enable();
}
else
{
cboFormat.disable();
}
Why doesn't this work? I have also previously set the format input to disabled.
This could be that you do not have a actionlistener on your combo box ? As Andrew suggested, there could be more reasons why your block does not work. If you pasted more code it would be easier to determine what the problem is. If however you are missing action listener on your combo box, code below.
public void actionPerformed(ActionEvent e) {
JComboBox cboBookType = (JComboBox)e.getSource();
String bookType= (String)cboBookType.getSelectedItem();
//and paste your ifs here
if("Ebook".equals.....){
...
}
... rest of code
}
And if you don't know what action listener is, its basically interface used by other classes to listen for an action event. i.e. user clicking button, or user selecting checkbox etc.
Dont use enable and disable try this and dont put it in the constructor because then it wont get updated you have to make a new event like itemchanged or itemstatechanged i dont know it exactly
if("Ebook".equals(cboBookType.getSelectedItem()))
{
cboFormat.setvisible(true);
}
else
{
cboFormat.setvisible(false);
}

How do I change the value of a JOptionPane from a PropertyChangeListener without triggering the listener?

I am trying to make a program to manage a group of sports players. Each player has an enum Sport, and SportManager has convenient factory methods. What I am trying to do is open a dialog that has a JTextField for a name and a combo box to choose a sport. However, I want to stop the user from closing the dialog while the text field is blank, so I wrote a PropertyChangeListener so that when the text field is blank, it would beep to let the user know. However, if the user puts in something in the text after setting off the beep, it doesn't trigger the listener and you can't close the dialog without pressing cancel because the value is already JOptionPane.OK_OPTION, and cancel is the only way to change JOptionPane.VALUE_PROPERTY. So I tried to add
message.setValue(JOptionPane.UNITIALIZED_VALUE);
within the listener. However this just closes the window right away without giving the user a chance to fill in the text field, presumably because it triggers the listener I just registered. How do I make it so that it will beep more than once and give the user a chance to fill in the field?
FYI newPlayer is the component I'm registering the action to.
Code:
newPlayer.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Object[] msg = new Object [4];
msg[0] = new JLabel("Name:");
final JTextField nameField = new JTextField();
msg[1]=nameField;
msg[2] = new JLabel("Sport: ");
JComboBox<Sport> major = new JComboBox<Sport>(SportManager.getAllSports());
msg[3]=major;
final JOptionPane message = new JOptionPane();
message.setMessage(msg);
message.setMessageType(JOptionPane.PLAIN_MESSAGE);
message.setOptionType(JOptionPane.OK_CANCEL_OPTION);
final JDialog query = new JDialog(gui,"Create a new player",true);
query.setContentPane(message);
query.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
message.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if (query.isVisible()&& (e.getSource() == message)&& (prop.equals(JOptionPane.VALUE_PROPERTY))) {
if(nameField.getText().equals("")&&message.getValue().equals(JOptionPane.OK_OPTION)){
Toolkit.getDefaultToolkit().beep();
message.setValue(JOptionPane.UNINITIALIZED_VALUE);
return;
}
query.dispose();
}
}
});
query.pack();
query.setVisible(true);
if(Integer.parseInt(message.getValue().toString())==JOptionPane.OK_OPTION){
players.add(new Player(nameField.getText(),(Sport)major.getSelectedItem()));
edited=true;
}
gui.show(players);
}
});
I don't think you can do it with JOptionPane but you can using using TaskDialog framework and few others.
You can also create a dialog yourself, attach change listeners to your fields and enable/disable OK button based on content of your fields. This process is usually called "form validation"
However, I want to stop the user from closing the dialog while the
text field is blank
I get where you are going, but Java Swing is not very good at this. There is no way you can prevent the listener from being called. A solution would be to ignore the call, but this is complicated to implement.
The way I solved this issue is to let the pop-up disappear, check the returned value and if it is null/empty, beep and re-open it until user fills something.
JOptionPane does not internally support validation of inputs (Bug Reference). Your best bet is to create your own custom JDialog which supports disabling the OK button when the input data is invalid.
I'd recommend reading the bug report since other people talk about it and give workarounds.
However, I want to stop the user from closing the dialog while the text field is blank
The CustomDialog example from the section in the Swing tutorial on Stopping Automatic Dialog Closing has a working example that does this.
After taking a quick look at your code and the working example I think your code should be something like:
if (query.isVisible()
&& (e.getSource() == message)
&& (prop.equals(JOptionPane.VALUE_PROPERTY)))
{
if (message.getValue() == JOptionPane.UNINITIALIZED_VALUE)
return;
if (nameField.getText().equals("")
&& message.getValue().equals(JOptionPane.OK_OPTION))
{
Toolkit.getDefaultToolkit().beep();
message.setValue(JOptionPane.UNINITIALIZED_VALUE);
}
else
query.dispose();
}
Otherwise, I'll let you compare your code with the working code to see what the difference is.
One way to solve this problem is to add a Cancel and Ok button to your dialog. Then, disable closing the popup via the X in the corner, forcing the user to click either Cancel or Ok to finish/close the dialog. Now, simply add a listener to the text field that will disable the Ok button if the text field is blank.
Judging from your code I assume you can figure out how to implement these steps, but if you have trouble let us know! Good luck!

text in text box

i am pretty new to the gwt framework and i am using it for building the ui of my web site,
i would like to make the text box have a text in it that once the user clicks on it for the first time, the text disappears. and in the rest of the time it behaves like a normal text box
any ideas on how to do it?
When you create the textbox, set the default text and add a keyboard listener:
TextBox box = new TextBox();
box.setText("Default Text");
box.addKeyboardListener(this);
defaultValue = true; // this is a global boolean value
Then have your class implement KeyboardListener leaving them all blank except:
public void onKeyPress(Widget arg0, char arg1, int arg2)
{
if(defaultValue)
{
box.setText = "";
defaultValue = false;
}
}
you can add a clickHandler to the box.
Within the handler you do something as easy as:
if(text==DEFAULT_TEXT)
{
text==""
}
If someone is going to write again the same DEFAULT_TEXT it would get wiped out again.
If you want to avoid that add boolean variable in the check expression.
Can't tell it for GWT, but a general approach could be:
use a variable to flag, whether the text box is 'initialized' or 'in use'
add a listener to the text widget (I'd use a KeyboardListener and make the text disappear when the user starts entering text and not on the first - maybe accidental - mouse click)
When the listener receives the first event for the widget (flag = 'initialized'), clear the flag and replace the text inside the text field with the actual keystroke.
(for a click listener: upon the first click on the widget clear the flag and the text box.)

Categories

Resources