我有一个包含文本字段(红色,绿色,蓝色)和滑块(红色,绿色,蓝色)的面板。用户应该能够利用他们喜欢的任何一个,相应的组件应该更新。 (例如,在红色文本字段中输入100应将红色滑块移动到100)。
由于我希望滑块在插入或删除文本时更新 ,因此我创建了一个简单的DocumentListener。但是,我收到错误消息" java.lang.IllegalStateException:尝试在通知中进行变异。"我的程序对是否应该首先更新滑块或文本字段感到困惑。有没有办法解决这个问题?我将在下面发布我的两个课程,并附上GUI的照片以供快速参考。
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) {
}
}
答案 0 :(得分:0)
这可能会有点晚,但本周我正在研究一个Java项目,我遇到的问题和你上面描述的一样。
在寻找解决方案时,我偶然发现了你的问题。由于它还没有答案,我认为回到这里描述我是如何解决问题可能会有所帮助(也许它将来会帮助你或其他人)。
因此,似乎Swing API通过提供一个名为getValueIsAdjusting的非常好的方法来帮助我们。此方法是for (int i=0; i < results.Count; i++)
{
if (results[i].StartsWith("\""))
results[i] = results[i].Remove(0, 1);
if (results[i].EndsWith("\""))
results[i] = results[i].Remove(results[i].Length - 1, 1);
}
类的一部分。
这是如何解决问题的?
我们修改了JSlider
实施中的stateChanged
方法:
ChangeListener
@Override
public void stateChanged(ChangeEvent ce) {
JSlider source = (JSlider)ce.getSource();
if (source.getValueIsAdjusting()) {
if (source == sldRed)
txtRed.setText(Integer.toString(sldRed.getValue()));
else if (source == sldGreen)
txtGreen.setText(Integer.toString(sldGreen.getValue()));
else if (source == 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));
}
指令仅在您仍在“调整”滑块时才会发生if (source.getValueIsAdjusting())
(这意味着您仍然使用鼠标拖动它)。
将值写入setText
会触发滑块的JTextField
方法,但 NOT 会调用stateChanged
,因为滑块价值不是“调整”。
因此,你摆脱了异常。