I have a panel containing textfields (red, green, blue) and sliders (red, green, blue). Users are supposed to be able to utilize whichever they prefer, and the corresponding component should update. (E.g., entering 100 into the red textfield should move the red slider to 100).
Since I want the sliders to update as text is being inserted or removed, I created a simple DocumentListener. However, I get the error message "java.lang.IllegalStateException: Attempt to mutate in notification." My program gets confused as to whether it should updated the slider or textfield first. Is there a way to fix this problem? I will post my two classes below, and a photo of the GUI will also be attached for quick reference.
public class ColorChooser extends javax.swing.JPanel implements ChangeListener {
private Vector listeners;
public ColorChooser() {
initComponents();
listeners = new Vector();
sldRed.addChangeListener(this);
sldGreen.addChangeListener(this);
sldBlue.addChangeListener(this);
txtRed.setText("0");
txtGreen.setText("0");
txtBlue.setText("0");
Document docRed = txtRed.getDocument();
docRed.addDocumentListener(new MyDocumentListener(txtRed, sldRed));
Document docGreen = txtGreen.getDocument();
docGreen.addDocumentListener(new MyDocumentListener(txtGreen, sldGreen));
Document docBlue = txtBlue.getDocument();
docBlue.addDocumentListener(new MyDocumentListener(txtBlue, sldBlue));
}
// Variables declaration - do not modify
private javax.swing.JLabel labelBlue;
private javax.swing.JLabel labelGreen;
private javax.swing.JLabel labelRed;
private javax.swing.JSlider sldBlue;
private javax.swing.JSlider sldGreen;
private javax.swing.JSlider sldRed;
private jcolorchooser.JColorIntegerField txtBlue;
private jcolorchooser.JColorIntegerField txtGreen;
private jcolorchooser.JColorIntegerField txtRed;
// End of variables declaration
@Override
public void stateChanged(ChangeEvent ce) {
if (ce.getSource() == sldRed) {
txtRed.setText(Integer.toString(sldRed.getValue()));
}
if (ce.getSource() == sldGreen) {
txtGreen.setText(Integer.toString(sldGreen.getValue()));
}
if (ce.getSource() == sldBlue) {
txtBlue.setText(Integer.toString(sldBlue.getValue()));
}
int r = sldRed.getValue();
int g = sldGreen.getValue();
int b = sldBlue.getValue();
Color color = new Color(r,g,b);
fireColorEvent(new ColorEvent(this,color));
}
private void fireColorEvent(ColorEvent colorEvent){
Vector v;
synchronized(this){
v = (Vector)listeners.clone();
}
int size = v.size();
for(int i=0; i<size; i++){
ColorListener colorListener = (ColorListener)v.elementAt(i);
colorListener.changeColor(colorEvent);
}
}
public void addColorListener(ColorListener colorListener){
listeners.addElement(colorListener);
}
public void removeColorListener(ColorListener colorListener){
listeners.removeElement(colorListener);
}
}
//DocumentListener Class
public class MyDocumentListener implements DocumentListener {
private JColorIntegerField jColorIntegerField;
private JSlider jColorSlider;
public MyDocumentListener(JColorIntegerField jColorIntegerField,
JSlider jColorSlider) {
this.jColorIntegerField = jColorIntegerField;
this.jColorSlider = jColorSlider;
}
public void insertUpdate(DocumentEvent de) {
if (jColorIntegerField.getText().equals("")) {
jColorSlider.setValue(0);
}
else {
jColorSlider.setValue(Integer.parseInt(
jColorIntegerField.getText()));
}
}
@Override
public void removeUpdate(DocumentEvent de) {
if (jColorIntegerField.getText().equals("")) {
jColorSlider.setValue(0);
}
else {
jColorSlider.setValue(Integer.parseInt(
jColorIntegerField.getText()));
}
}
@Override
public void changedUpdate(DocumentEvent de) {
}
}