java Swing how consume document event - java

I want consume a DocumentEvent captured into insertUpdate method of a DocumentListener
I don't see any way to prevent as a KeyEvent (e.consume()).
I don't want use the key listener because can't prevent the clipboard events (Copy Paste).
How I work with this events?
How I can raise Document events since cose?
Isbn13TextField.getDocument().addDocumentListener(new DocumentListener(){
public void insertUpdate(DocumentEvent e) {
e.consume(); //Not Exists, How consume a copy paste?
}
public void removeUpdate(DocumentEvent e) {}
public void changedUpdate(DocumentEvent e) {}
});

Depending on what it is you are trying to achieve...
You could...
Use a DocumentFilter which will allow you to filter input before it reaches the underlying Document. This is used by the Document itself and therefore is not depended on how the content is being added/removed from the Document but the Document itself.
Take a look at Text Component Features and Implementing a Document Filter in particular and here for examples
You could...
Make the field non-editable...
Isbn13TextField.setEditable(false)

How consume a copy paste?
You can't. A DocumentEvent is generated AFTER the Document has already been updated.
If you just want to disable the copy/paste functionality of a text field then you can remove the Key Bindings:
KeyStroke copy = KeyStroke.getKeyStroke("control C");
textField.getInputMap().put(copy, "none");

Related

FocusListener for all controls of a Composite

I've written code for a Composite containing multiple controls (StyledTexts, Buttons, etc.).
I wanted to implement a FocusListener for the whole Composite (not only for one of the controls inside of it), but the FocusListener did not do anything.
I tried to implement it myself, and my attempt was: Add a FocusListener to every Control inside the composite and handle these events.
While trying to do so, I found some problems:
When two controls have a FocusListener and I change the focus from one to the other, the FocusLost event is fired before the FocusGained
So I can't find out if the focus was given to one of the other controls in my composite, or if the composite lost the focus completely.
Note: I tried using Display.getFocusControl() inside the focusLost(...) method, but it only returns the control from which the focus is taken!
My question: Is it possible to find out which control will receive the focus next while being inside the focusLost(...) method?
If not: Is there any other way to implement a FocusListener for a Composite?
At the time the focusLost() event is sent, it isn't yet known which control (if any) will receive the focus.
You can add a display filter that will inform you whenever a control within your entire application gains focus. Within your ' Listener` implementation, you can save the text input whenever a control gains focus that is not contained in the composite. For example:
Listener listener = new Listener() {
#Override
public void handleEvent( Event event ) {
if( event.widget != text || event.widget != fontButton || ... ) {
save();
}
}
};
display.addFilter( SWT.FocusIn, listener );
Make sure to add the listener only while the observed composite is alive. Remove the filter when the composite is disposed of.
display.removeFilter( SWT.FocusIn, listener );
#RüdigerHermanns works pretty good, but for the sake of completeness I'll post my solution here too:
I've written listeners for SWT.Activate and SWT.Deactivate in my composite:
public MyComposite(Composite parent, int style)
{
super(parent, style);
createGuiElements(this);
this.addListener(SWT.Deactivate, new Listener()
{
#Override
public void handleEvent(Event event)
{
for (FocusListener listener : focusListeners) listener.focusLost(new FocusEvent(event));
}
});
this.addListener(SWT.Activate, new Listener()
{
#Override
public void handleEvent(Event event)
{
for (FocusListener listener : focusListeners) listener.focusGained(new FocusEvent(event));
}
});
}
which notify all focusListeners on the Composite.

JTextField respond to key event AFTER the text is updated

Right now, when I add a KeyListener to a JTextField, I get an event, then the text updates. But what I need is for the KeyListener to respond after the text is updated. How would I go about doing that? Right now, I am setting a 10-millisecond delay to the response of the KeyListener in another thread, which is sufficient for the text to update and the user to not notice.
Don't use a KeyListener. Swing has newer and better API's than AWT.
Instead you should be adding a DocumentListener to the Document of the JTextfield
A DocumentEvent is generated whenever the Document is updated.
Read the section from the Swing tutorial on How to Write a DocumentListener for more information and examples.
So.... ummmm i know it's kind'a late X)
I kind'a gone around that by using the keyReleased method I noticed that the text gets updated before the key event it should give you something like this
JTextField jtf = new JTextField();
jtf.addKeyaddKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
// not here
}
#Override
public void keyReleased(KeyEvent e) {
// not here
}
#Override
public void keyPressed(KeyEvent e) {
//do the stuff here
}
});
note that I am not sure why it works but I would think that it has something to do with the typing speed or something, also I am not an expert but i wanted to help (that problem drove me crazy for a couple days) if i am saying any stupid stuff pleas let me know !

can't clear jtextfield using Documentlistener

i have a textfield, when the user inserts a certain number of characters the program should put it in a JTable and clears the textfield, but it fires an event for Jtextfield.setText("");
Here's my code:
jTextField2.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent e) {
printIt();
}
#Override
public void removeUpdate(DocumentEvent e) {
}
#Override
public void changedUpdate(DocumentEvent e) {
}
private void printIt() {
//DocumentEvent.EventType type = documentEvent.getType();
String code=jTextField2.getText().trim();
// if(type.toString().trim().length()==13)
if (code.length()==4) {
list.add(code);
mod.addRow(new Object[]{code});
jTextField2.setText("");
}
}
});
}
To update the text field while using a DocumentListener you need to wrap the code in a SwingUtilities.invokeLater() so the code is executed after all updates have been done to the Document.
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
jTextField2.setText("");
}
});
You can't modify the textfield's doucment inside a DocumentListener. Use a DocumentFilter to modify text.
Document listeners should not modify the contents of the document; The
change is already complete by the time the listener is notified of the
change. Instead, write a custom document that overrides the
insertString or remove methods, or both.
In another part.
You may want to change the document's text within a document listener.
However, you should never modify the contents of a text component from
within a document listener. If you do, the program will likely
deadlock. Instead, you can use a formatted text field or provide a
document filter.
All quotes from here
Tutorial How to write a DocumentFilter

Using Actions with DocumentListener

I'm developing an application where I want something to be triggered both by the user updating the contents of a JTextArea, or manually via pressing a JButton.
I have done the first part using a DocumentListener and putting the relevant code in its insertUpdate method.
I haven't used Actions before, but I've heard they are useful for situations where you need something to be triggered by multiple controls. Is it possible to trigger the action from the DocumentListener? Is it a good idea to use Actions at all, or should I just put my code in a normal method?
(in the constructor):
textAreaInput.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
// do something
}
public void removeUpdate(DocumentEvent e) {}
public void changedUpdate(DocumentEvent e) {}
});
and the Action, which is a field:
Action doSomething = new AbstractAction("Do Something!") {
#Override
public void actionPerformed(ActionEvent e) {
// do it
}
};
clarification:
The JTextArea will receive text that is pasted in by the user, which I want to parse automatically. The parsing depends on other values set elsewhere in the GUI; if the user changes these other values, he may want to re-parse the text, hence the need to perform the same action by pressing a button.
I want something to be triggered both by the user updating the contents of a JTextArea, or manually via pressing a JButton.
This doesn't make sense to me.
Why would clicking a button invoke the same Action as a user typing text into a text area?
I haven't used Actions before, but I've heard they are useful for situations where you need something to be triggered by multiple controls
That statement is meant for controls that the user clicks, like JMenuItems, JButtons or hitting Enter on a text field. In general they can be used when you use an ActionListner.
A DocumentListener is not an ActionListener so as I stated earlier the use of an Action doesn't seem appropriate.
I think you need to clarify your requirement.
Edit, based on clarification
if the user changes these other values, he may want to re-parse the text
Why does the user have a choice? If you change the font, text, foreground, background of a text area, the component it automatically repainting, you don't have to ask for this to be done. If you look at the code for these methods they always end up invoking the revalidate() and repaint() methods.
The parsing depends on other values set elsewhere in the GUI;
Sounds like you need a custom class. Maybe a ParsedTextArea or ParsedDocument. This class would contain the "properties" that can be set elsewhere in the GUI. It would implmenent the DocumentListener. It would also support your "parseTheText" method. So whenever a property is changed or a DocumentEvent is generated you automatically invoked the "parseTheText" method. This way you don't need a separate button and the component will always be in sync because the parsing is automatic.
You can invoke the actionPerformed() method, whether it's in an Action or not. There's an example here.
I think you need not create the Action object. You can add ActionListener to the Button just like you have added DocumentListener to the Document of the input. If I correctly understand your problem, may be you should do something like this:
textInput.getDocument().addDocumentListener(new DocumentListener(){
#Override
public void insertUpdate(DocumentEvent e) {
doIt();
}
#Override
public void removeUpdate(DocumentEvent e) {}
#Override
public void changedUpdate(DocumentEvent e) {}
});
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
doIt();
}
});
doIt() is a method in which you will do what you wanted to do.

how to Override FocusListener - Swing

The application i work with override the default JComboBox from swing. Leets Call it MyComboBox. This version of ComboBox implement the FocusListener and contains the two methods focusGained and focusLost.
Now, in one of the panel of the application, the form contains a ComboBox of this type:
MyComboBox aMyComboBox = new MyComboBox();
I want to add a listener on this like that :
aMyComboBox.addFocusListener(new FocusListener() {
public void focusLost(FocusEvent e) {
//Do something here
}
public void focusGained(FocusEvent e) {
//Do something else
}
});
But when i run the code, it never pass into these method but only execute the focusGained/lost from the MyComboBox class.
Is there a way to add a listener on an object that already implements FocusListener?
Additional FocusListener should work unless the instance used in MyComboBox consumes the event (AWT event consumption).
Try making an example with an ordinary JComboBox -- this will help narrowing down the cause of the problem.

Categories