How to make Enter key focus for a JButton in java swing?
i have done like this
btn_Login.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("enter key pressed");
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0,false), txt_Username.WHEN_FOCUSED);
but not working
I assume you want a specific button to be "pressed" if you just press Enter on a certain window.
To do this, you have to set the defaultButton on your RootPane of the current JFrame.
Here is an example:
JButton btn = new JButton();
JFrame frame = new JFrame();
frame.getContentPane().add(btn);
frame.getRootPane().setDefaultButton(btn);
That should give you the expected result.
Thanks to all! Here are some notes that I found out to fix the enter problem for the Nimbus Look and fell.
The enter key works with linux but not with windows ( Nimbus ).
For windows the actual "doClick" of the button is done with space ( Key Char 32 ).
It's possible to set the "enter" to do a click, but it must be done AFTER setting your Nimbus Look and Feel.
Here is the code that is used in my application.
UIManager.setLookAndFeel(new NimbusLookAndFeel());
//- hack pour que les bouttons qui ont le focus fassent un doClick
//- lorsque "enter" est taper. Auparavant, c'etait l'espace qui
//- activait le doClick.
InputMap im = (InputMap)UIManager.get("Button.focusInputMap");
im.put( KeyStroke.getKeyStroke( "ENTER" ), "pressed" );
im.put( KeyStroke.getKeyStroke( "released ENTER" ), "released" );
( Sorry for my french comments ! ).
Related
Say I am making a program that keeps track of people's favorite food. I have a dropdown, as such:
String foods = { "Pizza", "Burgers", "Pasta", "Bacon" };
String favoriteFood = JOptionPane.showInputDialog(null, "What is your favorite food?", "Choice", JOptionPane.QUESTION_MESSAGE, null, foods, foods[0]));
JOptionPane.showMessageDialog(null, favoriteFood);
How do I make a part in the dropdown that is like "Choose now...", but if you click the "Choose now...", it doesn't become your choice? Thank you!
You may do it like this
String[] foods = { "Pizza", "Burgers", "Pasta", "Bacon" };
JComboBox<String> cb = new JComboBox<String>(foods);
cb.getModel().setSelectedItem("Choose now...");
cb.addHierarchyListener(hEv -> {
if((hEv.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && cb.isShowing()) {
JButton ok = SwingUtilities.getRootPane(cb).getDefaultButton();
ok.setEnabled(cb.getSelectedIndex() >= 0);
cb.addActionListener(aEv -> ok.setEnabled(cb.getSelectedIndex() >= 0));
} });
JPanel p = new JPanel(new GridLayout(0, 1, 0, 8));
p.add(new JLabel("What is your favorite food?"));
p.add(cb);
int choice = JOptionPane.showConfirmDialog(null,
p, "Choice", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
JOptionPane.showMessageDialog(null,
choice == JOptionPane.OK_OPTION? cb.getSelectedItem(): "no choice");
The first challenge is to set a (pre)selected value that is not part of the selectable choices. When you call setSelectedItem on a non-editable JComboBox, it will reject any values outside the model. However, we can set the selected value on the model directly, like in cb.getModel().setSelectedItem("Choose now...");
Then, to ensure that we won’t confuse this initial selection with an actual selection, we have to disable the “Ok” button until a choice from the list has been made (cb.getSelectedIndex() >= 0). To get the “Ok” button itself, we wait until the entire AWT hierarchy has been constructed and get the default button.
A possible solution using the JOptionPane is shown below. In this code the JDialog is more or less manually created. The OK button and available options are then pulled from the JOptionPane and the OK button is only enabled when anything other than 'Choose from...' is selected.
String[] foods = new String[]{"Choose now...", "Pizza", "Burgers", "Pasta", "Bacon"};
JOptionPane pane = new JOptionPane("What is your favorite food?", JOptionPane.QUESTION_MESSAGE,
JOptionPane.OK_CANCEL_OPTION, null,
null, null);
pane.setWantsInput(true);
pane.setSelectionValues(foods);
pane.setInitialSelectionValue(foods[0]);
// create the dialog and select the initial value
JDialog dialog = pane.createDialog( null, "title" );
pane.selectInitialValue();
// find the OK Button and disable it by default
JPanel buttonPanel = (JPanel) pane.getComponent( 1 );
JButton ok = (JButton) buttonPanel.getComponent( 0 );
ok.setEnabled( false );
// find the JComboBox (the panel holding the available options)
JPanel childPanel = (JPanel) ((JPanel) pane.getComponent( 0 )).getComponent( 0 );
JPanel innerPanel = (JPanel) childPanel.getComponent( 1 );
JComboBox options = (JComboBox) innerPanel.getComponent( 1 );
// add an action listener to the JComboBox; enable the OK button if a valid option is selected
options.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if ( options.getSelectedIndex() == 0 ) {
ok.setEnabled( false );
} else {
ok.setEnabled( true );
}
}
});
// show the dialog
dialog.show(); // <--- note this one is deprecated, should probably use: dialog.setVisible( true );
dialog.dispose();
// get the selected value
String value = pane.getInputValue().toString();
I have the following line of code
JOptionPane.showMessageDialog(rootPane, "Código incorreto\nPor favor verifique", "Atenção", JOptionPane.ERROR_MESSAGE);
that show this message here
How to center this 2 lines of text in the center of the box?
JLabel label = new JLabel("<html><center>Código incorreto<br>Por favor verifique");
label.setHorizontalAlignment(SwingConstants.CENTER);
JOptionPane.showMessageDialog(null, label, "Atenção", JOptionPane.ERROR_MESSAGE);
Try this one. Preview:
You may get it working with following code:
String message = "<html><body><div width='100px' align='center'>Código incorreto<br>Por favor verifique</div></body></html>";
JLabel messageLabel = new JLabel(message);
JOptionPane.showConfirmDialog(null, messageLabel, "Atenção", JOptionPane.DEFAULT_OPTION);
I've been trying to make a JTextArea display a certain String when F2 is pressed in a certain TextField, with no success as yet. Any help much appreciated.
My code may reveal how little programming experience I have:
final String ACTION_KEY = "this text";
public void actionPerformed(ActionEvent actionEvent) {
JTextField source = (JTextField) actionEvent.getSource();
System.out.println("Activated: " + source.getText());
textAreaInstructions.setText("this text");
}
};
KeyStroke F2 = KeyStroke.getKeyStroke("F2");
InputMap inputMap = timeStep.getInputMap();
inputMap.put(F2, ACTION_KEY);
ActionMap actionMap = timeStep.getActionMap();
actionMap.put(ACTION_KEY, actionListener);
EDIT: I'm now trying this code instead:
InputMap inputMap = timeStep.getInputMap();
Object actionSubmit = inputMap.get(KeyStroke.getKeyStroke("ENTER"));
Object actionSubmitSp = inputMap.get(KeyStroke.getKeyStroke("SPACE"));
System.out.println("actionSubmit for space = " + actionSubmitSp);
ActionMap actionMap = timeStep.getActionMap();
Action action = actionMap.get(actionSubmit);
System.out.println("actionSubmit = " + actionSubmit);
timeStep.getInputMap().put(KeyStroke.getKeyStroke("SPACE"),
actionSubmit);
EDIT:
This prints
actionSubmit for space = null
actionSubmit = notify-field-accept
Is this any use?
The problem was nothing to do with the code posted. It was that I'd saved a backup of the file in the same package as the original and forgot to change the code, so the backup was being implemented rather than the updated original. That cost me a lot of time. lol.
EDIT: so anyway, now that I know which file I'm running, I found that the following code (which I got here: http://blog.marcnuri.com/blog/.../2007/06/06/Detecting-Tab-Key-Pressed-Event-in-JTextField-s-Event-VK-TAB-KeyPressed) does what I wanted (for tab instead of F2, but would obviously work for F2 too, in which case the first line wouldn't be needed):
timeStep.setFocusTraversalKeys(
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.EMPTY_SET);
timeStep.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_TAB){
instruction = "tab pressed";
textAreaInstructions.setText(instruction);
lblTabEvent.setText(instruction);
// If you want to change the focus to the next component
timerInterval.grabFocus();
}
else {
textAreaInstructions.setText("got here, "+ e.getKeyCode());
}
}
});
I'm using JTextPane in an application for wiki source editing. I've added a simple spell checking functionality to it which underlines mispelled words by changing character attributes to a different style via StyledDocument.setCharacterAttributes.
There are only these two styles used: the default and the 'mispelled' one. The text editor control does word wrapping, which is the expected behavior.
My problem is that there are cases (not always, but is reproducible with a specific wiki document) this character attribute changing somehow disables the word wrapping. More specifically, I delete three lines from the middle of the document, and the next run of the spell checker, when resets the character attributes to the default style (before rerunning the spell checking), the word wrapping functionality gets disabled and it remains that way. If I undo the deletion, the word wrapping goes back to normal.
Commenting out the single line that resets the style:
editorPane.getStyledDocument().setCharacterAttributes(0, editorPane.getStyledDocument().getLength(), defaultStyle, true);
solves the issue.
EDIT 1
I've extracted the problem to a simple test case. Sorry for the long line, that example text is important to reproduce the bug (it has been randomized):
package jtextpanebug;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.WindowConstants;
import javax.swing.text.Style;
public class DemoFrame extends javax.swing.JFrame {
private final JButton btResetStyle;
private final JScrollPane scrollPane;
private final JTextPane textPane;
private final Style defaultStyle;
public DemoFrame() {
// Creating a simple form with a scrollable text pane and a button
scrollPane = new JScrollPane();
textPane = new JTextPane();
btResetStyle = new JButton();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
// The text pane's text is the scrambled version of my original test data,
// it is important because the problem depends on the pane's text
// (not every text makes it wrong)
textPane.setText("= Gernela Stuff Dogo to Wnko Obuat Oebrfe Disytung hte Iidnividal Oitpcs =\n\n== Elmyonrogit ==\n\n'''memidtaie-ngiebhro opnits''' - 2 points, \nwihhc nac eb ense ot eb mmiieadte hnigeorbs fo haec othre. \nThere si no strict | cxeat defiintoin. \nEth etipcur owebl shsow sa an example optins dna the rispa \nienbg mimedtiea iebnghsor ear ncnoetced.\n\n[[Amieg:einogrhb_pinsot.pgn]]\n\n'''enihgorb optnsi distacne''' - het avaeegr of sdntaisce \nderemitedn by het mimeidate-hieobngr tonpi ipras. \n\n'''lalw''' - a iotpntes nepgesnietrr a llwa, with toerh orwds: 2 apraelll, \nevyr sloce sraufce picsee. Heer is an xamelpe. \nIt is eualgttandri ofr eterbt zisiuaitovlan.\n\n[[Gimae:llwa.npg]]\n\n'''addtaiilon emmory reeueimtnqr of na laigorthm''' - \n(eth kepa mmeory suaeg fo teh nltpiaciapo ndirug the excteouin of eht grlaotihm) - \n(hte moeymr sueag fo hte loragitmh befoer ro ftrea eht ucxeeiont of the laogrihmt)\n\n== Het Input Pnoitset Ash to Repnrsete Ufscear Arsnoelbay Elwl ==\n\nIf tno efisciped toehrwsie yb hte cdoritnpsei of an aoglirthm, \nhetn hte eqtunrmeersi of it are heste:\n\n* Ifsrt fo all the poisentt umst reprseent urfseac, not urvec ro uvomel or nayithng eesl.\n* Awlls aym otn eb tniehnr tanh at least 3 * fo ienhbgro-tpoin-sidenact.\n* Dseeg amy ton be rhserap tnha 70 grdesee (as het agnle fo eht trmeaial) nda husdol be ta tleas 290 redeseg (ni caes fo cnvocae eedgs).\n* Onpti edintsy amy ont vayr oto humc \n** Het angre fo the coall ption desitnsei of a igsenl pisnotte nutip ushold eb sallm. Ahtt is: teh orait of het oclla oitnp idsentise oarund any 2 ipnost lsdhou eb lmitied.\n** Hte lcoal noipt deisynt ushlod otn ahencg sdduelyn (gliftyscaiinn ni a hotsr idnsteac). \n\nYreftntunaoul the largoimths cna tno yb ethmsevesl \nhcekc these qutenmeserir nda usjt yden rnuning, \nso it si eth rseu's iyponerissbtil to ton extucee an raltghomi no a itseopnt \nthat does ont mete het aogitmlhr's terieseurmnq.\n\nIf eth rmeteriuqen fo na airlgmoth on its npuit is ont mte, then tobh hte ueavbhior nad hte srluet fo hte alghoritms si dinfeuned. \nTeh loirgamth amy nru rfo iinfntie long imet or rodpuce evry abd rselut, ro a eruslt htat oolsk good btu is nicrtroec. Ni htis scea rtehe si tno nay aguntreee toabu the tmniatreion of the iralgtmho ro eht lqutaiy fo the sreltu ecxept htat the nptapalcioi iwll ont carsh.\n");
scrollPane.setViewportView(textPane);
getContentPane().add(scrollPane);
btResetStyle.setText("Reset style");
btResetStyle.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
btResetStyleActionPerformed(evt);
}
});
getContentPane().add(btResetStyle);
pack();
// The default style, the problem happens when we reset the full document
// to it:
defaultStyle = textPane.addStyle("default", null);
}
private void btResetStyleActionPerformed(java.awt.event.ActionEvent evt) {
// When the button is pressed we reset the full document to the default
// style. In the original application this was periodically done as
// part of the spell checking
textPane.getStyledDocument().setCharacterAttributes(0, textPane.getStyledDocument().getLength(), defaultStyle, true);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new DemoFrame().setVisible(true);
}
});
}
}
Reproducing the issue:
Compile and run the class above
Try to resize the frame - word wrapping works
Locate and delete the three lines I copied below
Press the Reset style button
The word wrapping turned off
* Onpti edintsy amy ont vayr oto humc
** Het angre fo the coall ption desitnsei of a igsenl pisnotte nutip ushold eb sallm. Ahtt is: teh orait of het oclla oitnp idsentise oarund any 2 ipnost lsdhou eb lmitied.
** Hte lcoal noipt deisynt ushlod otn ahencg sdduelyn (gliftyscaiinn ni a hotsr idnsteac).
EDIT 2
Using the highlighter instead of styles solved my problem, but I'm still curious what was wrong with the original approach.
This looks like the same issue I asked about here : Strange text wrapping with styled text in JTextPane with Java 7.
As far as I know, this is a bug in Java 7, and it is not documented in Oracle's Java Bug Parade. I have still not found a workaround (using the highlighter is not an option in my case).
All I want to do is have a JOptionPane inputDialog with a JTextArea instead of a JTextField.
I tried putting the JTextArea inside of the Message parameter like so
Object[] inputText = new Object[]{new JLabel("Enter Graph Information"),
newJTextArea("",20,10)};
graphInfo=(String)JOptionPane.showInputDialog(null,
inputText,
"Create Graph",
JOptionPane.PLAIN_MESSAGE,
null,
null,
"");
But it still has the text field at the bottom and I cannot get the text from the JTextArea.
Is there any way to either remove the original text field and get the text from the jtextarea or replace the text field with the text area completely? I'm trying to avoid having to make a custom dialog if possible and this "seems" like something that should be easy to do?
You're on the right lines; you just need to use showConfirmDialog instead of showMessageDialog, which allows you to pass any Component as your "message" and have it displayed within the JDialog. You can then capture the contents of the JTextArea if the user clicks OK; e.g.
int okCxl = JOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor(this),
textArea,
"Enter Data",
JOptionPane.OK_CANCEL_OPTION)
if (okCxl == JOptionPane.OK_OPTION) {
String text = textArea.getText();
// Process text.
}
If you want to show a JLabel in conjunction with your JTextArea you can create and pass in a JPanel containing both Components; e.g.
JTextArea textArea = ...
JPanel pnl = new JPanel(new BorderLayout());
pnl.add(new JLabel("Please enter some data:"), BorderLayout.NORTH);
pnl.add(textArea, BorderLayout.CENTER);
JOptionPane.show...