Why the textchangelistener is slow? - java

I'm looking for a solution for my problem. I created a class that customize a TextField and I'm using TextChangeListener to change the value of field. Every number that user enter the change(format) is taken. Works, but the change is very slow I want it to be faster.
Here's how I'm doing.
public class CpfField extends TextField implements TextChangeListener{
private final StringBuilder CPF = new StringBuilder();
public CpfField(){
super("CPF");
setImmediate(true);
setMaxLength(14);
addTextChangeListener(this);
}
//change(format) values
#Override
public void textChange(TextChangeEvent event) {
if(!event.getText().trim().isEmpty()){
if(event.getText().length() == 3){
CPF.append(event.getText());
CPF.insert(3,".");
}else if(event.getText().length() == 7){
CPF.setLength(0);
CPF.append(event.getText());
CPF.insert(7,".");
}else if(event.getText().length() == 11){
CPF.setLength(0);
CPF.append(event.getText());
CPF.insert(11,"-");
}else{
CPF.setLength(0);
CPF.append(event.getText());
}
}else{
CPF.setLength(0);
setValue("");
}
setValue(CPF.toString());
}
}
How to change values faster ?

Setting the TextChangeEventMode to EAGER would result to trigger the event after each key is pressed. That seems often a bit too fast and too much overhead.
A TextChangeEvent is triggered when there is a pause in editing the text. The length of the pause can be modified with setInputEventTimeout().
Try to set an appropriate InputEventTimeout.
Hint:
If a ValueChangeEvent would occur before the timeout period, a
TextChangeEvent is triggered before it, on the condition that the text
content has changed since the previous TextChangeEvent.

Take a look here: https://vaadin.com/book/-/page/components.textfield.html under 5.8.4. Text Change Events. By default text change event mode is LAZY. What you want to do is probably:
setTextChangeEventMode(TextChangeEventMode.EAGER);

Related

I cannot clear my JTextArea, how can I clear the JTextArea?

It's a prototype for a virtual therapist, mainly for Java practice purposes. I've been trying to clear this JTextArea for 2 days now.
I've cleaned and rebuilt which got me through a few other hurdles, I'm at a loss for what to try. setEnabled() is coded out because I was just trying it on and off with different methods. Everything but the clear button works fine. I get a response in the text area after pressing enter with JTextField input. But it just won't clear.
public void actionPerformed(ActionEvent event)
{
String inp = event.toString(); //this is input in a JTextField
if(inp.contains("sad") || inp.contains("lonely"))
{
txtArea.setText(response1);
}else if(inp.contains(""))
{
txtArea.setText(response2);
}
else if(event.getSource() == clear) //clear is a button
{
//clear.setEnabled(true);
txtArea.setText(""); //I've tried selectAll(), replaceSelection()
}
}
From what I can see in your code this might help with the clear problem. In your code the if branch for the clear can never be reached due to the else after an condition(contains an emty string) that is always true. I moved it to the front - so it is reachable.
I can't say for sure from your posted code, but the event.toString() looks also suspicious as well as the last(in the changed code below) condition, that is always true.
//this looks odd/suspicious to me too!
String inp = event.toString(); //???!!! this is input in a JTextField
/* rather something like
* if(event.getSource() instanceof JTextField){
* inp = ((JTextField)event.getSource()).getText();
* }
*/
if(event.getSource() == clear) { //clear is a button
//clear.setEnabled(true);
txtArea.setText(""); //I've tried selectAll(), replaceSelection()
} else if(inp.contains("sad") || inp.contains("lonely")) {
txtArea.setText(response1);
} else if(inp.contains("")) { //??? always true!! rather: inp.equals("") or inp.isEmpty() ...
txtArea.setText(response2);
}

doClick(), and Simon: All buttons will unpress at the same time instead of individually

Hi I'm new to stackoverflow so bear with me if I make mistakes.
I'm making this Java Simon Says Game for a class project. It works by a random number generator for each sequence#. I show the sequence through doClick() but remove the actionlisteners beforehand and add it afterwards.
The problem is the buttons won't unpress or unarm until all other buttons have been pressed. I've tried using thread.sleep to put a delay between each if...else statements yet it only stays pressed for longer. I've tried updating the gui through repaint(), revalidate(), updateUI() within the try... catch of the thread.sleep but that didn't work either.
I've realized this issue is mainly cosmetic because when I tried implementing setPressed or setArmed it said it wasn't being pressed but it looked pressed.
Here is the code snippet in it's most simplest form without thread.sleep or my previous attempts in comments.
public void sequence2() //This is where the issue happens. The buttons won't unpress until every button has been pressed.
{
level.setText(" Level 2"); //Level indicator
Green.removeActionListener(Listener);
Red.removeActionListener(Listener);
Yellow.removeActionListener(Listener);
Blue.removeActionListener(Listener);
if(sequence1 == 1)
{
Green.doClick(300); //Programmatically clicks the button
}
else if(sequence1 == 2)
{
Red.doClick(300);
}
else if(sequence1 == 3)
{
Yellow.doClick(300);
}
else if(sequence1 == 4)
{
Blue.doClick(300);
}
if(sequence2 == 1)
{
Green.doClick(300);
}
else if(sequence2 == 2)
{
Red.doClick(300);
}
else if(sequence2 == 3)
{
Yellow.doClick(300);
}
else if(sequence2 == 4)
{
Blue.doClick(300);
}
Green.addActionListener(Listener);
Red.addActionListener(Listener);
Yellow.addActionListener(Listener);
Blue.addActionListener(Listener);
}
I'm very new to java so I'm not skilled in multithreading or working on the Event Dispatch Thread for that manner. But if that's the only solution I'll need some more help with that.
I have the full code in a zip file with previous attempts commented out if that will help.
https://drive.google.com/file/d/0Bxg4WleC9jD2VFhoZmZBNjV6Vkk/view?usp=sharing
Invoking doClick() may be an awkward choice for this, as it uses a Timer internally. Instead, use a JToggleButton, which will allow you to control each button's appearance based on its selected state using setSelected(). A complete example is shown in the game Buttons. In the ActionListener of your Swing Timer, select the current button, play its note and increment the sequence index. When all notes have been played, unselect all the buttons.
Addendum: Can you show how you implement the timer?
In outline, given a suitable list of toggle buttons:
private static final int MAX = 4;
List<JToggleButton> buttons = new ArrayList<JToggleButton>(MAX);
private int i;
The timer's listener might look like this:
#Override
public void actionPerformed(ActionEvent e) {
Object src = e.getSource();
JToggleButton b = buttons.get(i);
if (i > MAX) { // reset i and all the buttons
for (JToggleButton b : buttons) {
b.setSelected(false);
}
timer.stop();
i = 0;
} else {
b.setSelected(true);
// play tone i
i++;
}
}
A toggle button's item listener should update the button's appearance as indicated by its state:
#Override
public void itemStateChanged(ItemEvent e) {
JToggleButton b = (JToggleButton) e.getItem();
if (b.isSelected()) {
// change icon, color etc.
} else {
// restore icon, color etc.
}
}

How to perform white box testing on void methods?

I am trying to perform white box testing on the method below. It's a method for blinking an array list (lightUpSequence) of JButtons in Swing using a timer.
My question is as follows:
since this is a void method, how would one check the expected output? I plan to create different sizes of array lists as the inputs. For white box testing, is one allowed to add any codes such as print/counter statements inside the method being tested? I feel hesitant to add any modifications to the method and think that the method should be tested as is.
Thank you very much.
private void blinkSequence() {
final Timer timer = new Timer(BLINKING_TIMER_DELAY, null);
timer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (lightUpSequence.size() == 0) {
timer.stop();
}
// Turn button ON
if (!isON && lightUpSequence.size() > 0) {
int elementIndex = lightUpSequence.get(0);
buttonArrayList.get(elementIndex).setBackground(
Color.yellow);
isON = true;
// Turn button OFF if it's ON already. Then remove the
// element.
} else if (isON && lightUpSequence.size() > 0) {
int elementIndex = lightUpSequence.get(0);
buttonArrayList.get(elementIndex).setBackground(null);
lightUpSequence.remove(0);
isON = false;
}
}
});
timer.start();
timer.setRepeats(true);
}
Well, there is nothing stopping you from making it return a boolean, but if you want to keep it the way it is you can use assert statements.
have a look at assert
For testing void method I use the following startegy:
Granulize the variables of the method through globalizing them.
So if you have an array, check the size before and after calling it.
If the size is the same, check the state of the objects in the array and compare them as before and after calling the method, like if they are lit or not.
In this way you can effectively comply to the white box testing rules.

Capturing keyboard combinations globally on the entire application to show hidden JDialog in Java

I'm going to make a hidden dialog in my application that get visible with a keyboard combination (e.g. Five sequent Ctrl+Shift+i).
How Can I capture keyboard combination strokes globally on the entire application?
Thanks
FullScreenTest is an example that shows how to use Action and Key Bindings in this context. You could substitute KeyEvent.VK_I and the relevant KeyStroke modifiers. Your action listener can keep count of how often it's been triggered.
I solved it by defining a DispatcherListener:
class DispatcherListener implements KeyEventDispatcher{
private int level=0;
public boolean dispatchKeyEvent(KeyEvent e) {
if(e.getID() == KeyEvent.KEY_RELEASED){
if(e.isControlDown() && e.isShiftDown()){
if(this.level==0 && e.getKeyCode()==KeyEvent.VK_S){
level++;
}else if(this.level==1 && e.getKeyCode()==KeyEvent.VK_H){
level++;
}else if(this.level==2 && e.getKeyCode()==KeyEvent.VK_O){
level++;
}else if(this.level==3 && e.getKeyCode()==KeyEvent.VK_W){
level=0;
this.showHiddenWindow((JFrame)SwingUtilities.getRoot(e.getComponent()));
}else{
level=0;
}
//System.out.println( "level: " + level );
}
}
return false;
}
and used it as this:
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher( new DispatcherListener());
Thank you all

weird result (java event-handling code)

public void itemStateChanged(ItemEvent event)
{
if(event.getSource() == doctorBox)
{
if (doctorBox.isSelected() == true)
JOptionPane.showMessageDialog(null, "you are a doctor");
else if (doctorBox.isSelected() != true)
JOptionPane.showMessageDialog(null, "you are not a doctor");
}
}
when the application is run... the checkbox is by default unchecked
when I check the "doctorBox" ... I get two dialog boxes popping together: "you are a doctor" and "you are not a doctor", also the checkbox doesn`t get checked!
why does that happen? how do I change the code to work correctly?
Here are some great samples. Remove all CheckBoxes except one and make sure you have a single listener to a single CheckBox per the details at the provided link. My guess is that there is strangeness occurring due to the way in which the listeners have been added in conjunction with the CheckBoxes.
Couple things to help you
for your logic, Since you know that the choice is either on or off, try the following
if(doctorBox.isSelected())
//do something
else
//do something else
with the checkbox not getting selected, change from an ItemListener to an ActionListener.
private class aListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == doctorBox){
if(doctorBox.isSelected())
JOptionPane.showMessageDialog(null, "you are a doctor");
else {
JOptionPane.showMessageDialog(null, "you are not a doctor");
}
}
}
}
If you look at your current code, and step through it using a debug you will see that your ItemListener gets fired 2 times. The first time checks it, the 2nd time it unchecks it. All on a single click. I cant explain the inner working of an itemListener in this case. ActionListener works much better

Categories

Resources