setDefaultButton not working as expected - java

public JoinChatClient(String serverAddress, String chatName)
{
chatWindow.getContentPane().add(sendButton, "South");
chatWindow.getContentPane().add(splitPane, "Center");
chatWindow.setSize(800,500);
sendButton.addActionListener(this);
chatWindow.setTitle("Chat Room");
chatWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
splitPane.setDividerLocation(350);
sendButton.setBackground(Color.gray);
sendButton.setForeground(Color.red);
outChatTextArea.setEditable(false);
inChatTextArea.setFont (new Font("default",Font.ITALIC,20));
outChatTextArea.setFont(new Font("default",Font.BOLD,20));
inChatTextArea.setLineWrap(true);
outChatTextArea.setLineWrap(true);
inChatTextArea.setWrapStyleWord(true);
outChatTextArea.setWrapStyleWord(true);
inChatTextArea.setText("Enter text to be sent here.");
outChatTextArea.setText("You can move the separator bar!");
inChatTextArea.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
if(inChatTextArea.getText().equals("Enter text to be sent here."))
{
inChatTextArea.setText("");
inChatTextArea.setFont(new Font("default",Font.BOLD,20));
}
}
public void focusLost(FocusEvent e) {
if(inChatTextArea.getText().isEmpty())
{
inChatTextArea.setFont (new Font("default",Font.ITALIC,20));
inChatTextArea.setText("Enter text to be sent here.");
}
}
});
chatWindow.getRootPane().setDefaultButton(sendButton);
chatWindow.setVisible(true);
}
I've looked over all the threads I could find concerning this, and I cannot figure out why hitting ENTER doesn't activate the actionPerformed method attached to sendButton. Is it because the text field has a FocusListener?
Things I've tried:
changing the statement to target the specific text field (inChatTextArea)
moved the setVisible statement to the end
targeted different parts of the GUI when hitting enter
Bear in mind I've only included the code that builds the GUI in an attempt to waste less of your time.
What I want: Ideally, I want to keep my FocusListener (or something like it) so that I can display the "text field hint." I would like to be able to hit ENTER to send the user's text while the inChatTextArea field is focused.

If a component on the JFrame has focus, and can accept an enter key press, such as one of the JTextAreas, then the enter presses will go to that component and not to the default button. For the default button to work, then the JFrame or the button or some other component that does not accept enter key presses, needs to have focus. I'm guessing that one of your JTextAreas has stolen the focus, and that this is messing you up.

This question is old, but I found it when having the same issue. So I hope others might find it useful.
I figured out that getRootPane() will return null if the component is trying to access the root pane too early, e.g. under construction of the component.
Hence, I propose to use SwingUtilities.invoke(Runnable) to postpone setting the default button on the root pane, and also to request the focus to the button.
So this method could be a helper method on a class to extend from:
protected void setDefaultButton(JButton button) {
// Uses invoke later, as getRootPane() might return null if the method is called under construction
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JRootPane rootPane = getRootPane();
if (rootPane != null) {
rootPane.setDefaultButton(button);
}
button.requestFocus(); // set the focus on the button
}
});
}

Related

Java Swing - Detecting a change in the document

For school, I'm attempting to recreate Microsoft's Notepad program using Java's Swing. I'm working on the saving and opening of .txt files, and I'm trying to figure out a way for the program to detect when a change has been made to the document. If a change has been detected and the user chooses to open or create a new file, I want the program to prompt the user if they would like to save their changes before continuing.
My thought for this was to create a flag, called documentChanged, that would initially be false, and which would be set to true whenever a change was made to the JTextArea. To detect this change, I thought of using a TextListener as follows:
public class JNotepad implements ActionListener
{
boolean documentChanged;
JTextArea notepad;
JNotepad()
{
documentChanged = false;
notepad = new JTextArea();
notepad.addTextListener(new TextListener() {
public void textValueChanged(TextEvent te) {
documentChanged = true;
}
});
}
}
However, I learned that Java classes are unable to implement multiple interfaces at once, and I'm already using ActionListeners to implement the items of my notepad's menu bar.
My question is, is there any way to use both TextListener and ActionListener (or any other listener) simultaneously in the same class? If not, what would be my best plan of action for detecting a change in the document?
It was answer in another post. See Text Changed event in JTextArea? How to?
And also see How to Write a Document Listener (DocumentListener) in Oracle, you will see an applet example.
How does your this even compile
notepad = new JTextArea();
notepad.addTextListener(new TextListener() {
// ....
}
since TextListeners are not defined to work with JTextAreas but rather with TextAreas, a completely different beast.
You should add a DocumentListener to your JTextArea's Document.
notepad.getDocument().addDocumentListener(new DocumentListener() {
void insertUpdate(DocumentEvent e) {
documentChanged = true;
}
void removeUpdate(DocumentEvent e) {
documentChanged = true;
}
void changedUpdate(DocumentEvent e) {
documentChanged = true;
}
});
Regarding
My question is, is there any way to use both TextListeners and ActionListeners (or any other listener) simultaneously in the same class?
Use of a DocumentListener has nothing to do with ActionListeners used elsewhere in your program since their domains are orthogonal to each other, i.e., the one has absolutely nothing to do with the other.

How to ignore the mouse events except the last one in Eclipse RCP

See below for code sample, the method handleMouseDoubleClick method will take seconds to run and open another layout screen containing buttons and links. End users may click many times on one listed item in the table control and create flood of mouse events, how can I handle the last mouse event only?
Table tableControl = (Table) control;
tableControl.addMouseListener(new MouseAdapter()
{
public void mouseDown(MouseEvent e)
{
handleMouseDown(e);
}
public void mouseUp(MouseEvent e)
{
handleMouseUp(e);
}
public void mouseDoubleClick(MouseEvent e)
{
handleMouseDoubleClick(e);
}
}
Create a flag field. Set it to true when handler was called. Initialize it with false.
You just need to check whether your screen is already initialized or not before creating another one.
Set the cursor to hourglass and/or disable the table, resetting these after the new "layout screen" is closed...

JTextField key listener is one behind after pasting

I am trying to check that the text in a JTextField matches a perticular pattern, and if it does / doesn't display a message the user. This is what I have so far:
public class input extends KeyListener{
// Some code here
final JTextField inputField = new JTextField(35);
// Some more code...
public void generate(){
// Some GUI code here...
inputField.addKeyListener(this);
}
public void keyPressed(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {
if(e.getSource() instanceof JTextField && e.getSource().equals(inputField)){
if(Pattern.matches("../../....", (JTextComponent) e.getSource()).getText())))
System.out.println("Yh, it works");
else System.out.println("EPIC FAIL (LOL)");
}
}
}
And it does actually work almost perfectly. However, if I paste something using CTRL + V, I have to type two more characters (as opposed to one) before the KeyListener registers that the string is different! So does any one have any idea's why?
Sorry if I have missed out any details - I have tried to make the post as short and concise as possible; so please don't hesitate to ask anything...
For starters, don't use a KeyListener for this type of problem as it is doomed to fail, and even if you get it to work, it's a kludge at best. Instead I'd use either an ActionListener if I wanted to do my checking after the user is completely done entering information, or a DocumentListener if I want to check input as a user is entering, but am not going to block that entering or change the displayed text, or a Document Filter if I'm going to check the input as the user is entering and block it or change it if it is not appropriate.

How can I know when the text of an editable JComboBox has been changed?

I have an editable JComboBox where I want to take some action whenever the text is changed, either by typing or selection. In this case, the text is a pattern and I want to verify that the pattern is valid and show the matches that result in some test data.
Having done the obvious, attach an ActionHandler, I have found that, for typing, the event seems to fire unreliably, at best (selection is fine). And when it does fire as a result of typing, the text retrieved (using getEditor().getItem(), since getSelectedItem() only gets the text when it was selected from the list) seems to be the text as it was when the last event was fired - that is, it's always missing the character was typed immediately before the action event was fired.
I was expecting the action event to fire after some short delay (500ms to 1 second), but it seems immediately fired upon keying (if it is fired at all).
The only workable alternative I can think of is to simply start a 1 second timer on focus-gained, killing it on focus-lost and doing the work as the timer action if the content is different from last time.
Any thoughts or suggestions?
The code snippets are not particularly interesting:
find.addActionListener(this);
...
public void actionPerformed(ActionEvent evt) {
System.out.println("Find: "+find.getEditor().getItem());
}
The action listener is typically only fired when you hit enter, or move focus away from the editor of the combobox. The correct way to intercept individual changes to the editor is to register a document listener:
final JTextComponent tc = (JTextComponent) combo.getEditor().getEditorComponent();
tc.getDocument().addDocumentListener(this);
The DocumentListener interface has methods that are called whenever the Document backing the editor is modified (insertUpdate, removeUpdate, changeUpdate).
You can also use an anonymous class for finer-grained control of where events are coming from:
final JTextComponent tcA = (JTextComponent) comboA.getEditor().getEditorComponent();
tcA.getDocument().addDocumentListener(new DocumentListener() {
... code that uses comboA ...
});
final JTextComponent tcB = (JTextComponent) comboB.getEditor().getEditorComponent();
tcB.getDocument().addDocumentListener(new DocumentListener() {
... code that uses comboB ...
});
You can use somthing like this:
JComboBox cbListText = new JComboBox();
cbListText.addItem("1");
cbListText.addItem("2");
cbListText.setEditable(true);
final JTextField tfListText = (JTextField) cbListText.getEditor().getEditorComponent();
tfListText.addCaretListener(new CaretListener() {
private String lastText;
#Override
public void caretUpdate(CaretEvent e) {
String text = tfListText.getText();
if (!text.equals(lastText)) {
lastText = text;
// HERE YOU CAN WRITE YOUR CODE
}
}
});
this sounds like the best solution
jComboBox.getEditor().getEditorComponent().addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) { //add your hadling code here:
} });

Java - change focus on key press

I am writing a Java Application for Data Entry using Eclipse and SWT. Naturally it has a great many Text objects.
What I would like to happen is that when user enters something into one field focus automatically changes to the next field.
Thanks in advance
final Text textBox = new Text(shell, SWT.NONE);
textBox.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (x.getText().length() == 1); {
x.traverse(SWT.TRAVERSE_TAB_NEXT);
}
}
});
final Text textBox = new Text(shell, SWT.NONE);
textBox.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent arg0) {
if (textBox.getText().equals("") == false) {
textBox.traverse(SWT.TRAVERSE_TAB_NEXT);
}
}});
You may also want to have a look at the VerifyListener interface. See this interesting blog post for a caveat though: http://eclipsenuggets.blogspot.com/2008/10/eclipse-bug-patterns-selfish-validation.html
I assume you want to change the focus after the field has been filled. I suggest using a DocumentListener (or whatever SWT calls it) to be notified of changes to the field's content: if it has the right number of characters, jump to the next field.

Categories

Resources