![](/img/trans.png)
[英]Java - Adding tab to JTabbedPane causing StackOverflowError (Disabling a firing ChangeEvent?)
[英]Java: Adding a text field to a ChangeEvent
我有一个家庭作业,我必须更改颜色选择器(它具有3个滑块,RGB并显示颜色),以便有文本字段,并且在该字段中键入值时,它也会更改滑块。 我有基本的想法,但是我很难找到更改文本字段的解决方案,它们只能与Action Event一起使用。 这是我的代码
package colorchooser;
import java.util.Vector;
import java.awt.Color;
import javax.swing.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
/**
*
* @author -
*/
public class ColorChooser extends javax.swing.JPanel implements ChangeListener, ActionListener{
private Vector listeners;
/**
* Creates new form ColorChooser
*/
public ColorChooser() {
initComponents();
listeners = new Vector();
sldRed.addChangeListener(this);
sldGreen.addChangeListener(this);
sldBlue.addChangeListener(this);
txtRed.addActionListener(this);
// Variables declaration - do not modify
private javax.swing.JButton btnSetColor;
private javax.swing.JLabel lblBlue;
private javax.swing.JLabel lblGreen;
private javax.swing.JLabel lblRed;
private javax.swing.JSlider sldBlue;
private javax.swing.JSlider sldGreen;
private javax.swing.JSlider sldRed;
private javax.swing.JTextField txtBlue;
private javax.swing.JTextField txtGreen;
private javax.swing.JTextField txtRed;
// End of variables declaration
@Override
public void stateChanged(ChangeEvent ce) {
int r = sldRed.getValue();
int g = sldGreen.getValue();
int b = sldBlue.getValue();
Color color = new Color(r,g,b);
fireColorEvent(new ColorEvent(this,color));
txtRed.setText(Integer.toString(r));
txtGreen.setText(Integer.toString(g));
txtBlue.setText(Integer.toString(b));
}
public void addColorListener(ColorListener colorListener){
listeners.addElement(colorListener);
}
public void actionPerformed(ActionEvent ae) {
if(ae.getSource()==btnSetColor){
try
{
if(Integer.parseInt(txtRed.getText()) <= 255){
sldRed.setValue(Integer.parseInt(txtRed.getText()));
}
else
{
txtRed.setText("0");
JOptionPane.showMessageDialog(this,"Error: Please enter a value equal to or less than 255");
}
if(Integer.parseInt(txtBlue.getText()) <= 255){
sldBlue.setValue(Integer.parseInt(txtBlue.getText()));
}
else
{
txtBlue.setText("0");
JOptionPane.showMessageDialog(this,"Error: Please enter a value equal to or less than 255");
}
if(Integer.parseInt(txtGreen.getText()) <= 255){
sldGreen.setValue(Integer.parseInt(txtGreen.getText()));
}
else
{
txtGreen.setText("0");
JOptionPane.showMessageDialog(this,"Error: Please enter a value equal to or less than 255");
}
}
catch (Exception ex)
{
JOptionPane.showMessageDialog(this,"Error: Please Enter Numbers");
txtRed.setText("0");
txtGreen.setText("0");
txtBlue.setText("0");
sldRed.setValue(Integer.parseInt(txtRed.getText()));
sldGreen.setValue(Integer.parseInt(txtGreen.getText()));
sldBlue.setValue(Integer.parseInt(txtBlue.getText()));
}
}
}
您可以看到我正在向滑块添加更改侦听器,但是我必须向txtRed添加操作侦听器,因为它不接受addChangeListener。 有什么想法可以解决吗?
谢谢!
创建一个可以处理已更改字段的方法...
protected void fieldWasChanged(JTextField field) {
try {
int value = Integer.parseInt(field.getText());
JSlider slider = null;
if (field == txtBlue) {
slider = sldBlue;
} else if (field == txtRed) {
slider = sldRed;
} else if (field == txtGreen) {
slider = sldGreen;
}
if (slider != null) {
slider.setValue(value);
}
} catch (NumberFormatException exp) {
exp.printStackTrace();
// Display error message
}
}
接下来,创建一个实现DocumentListener
接口的内部类...
public class DocumentHandler implements DocumentListener {
private JTextField field;
public DocumentHandler(JTextField field) {
this.field = field;
}
protected void documentUpdated() {
fieldWasChanged(field);
}
@Override
public void insertUpdate(DocumentEvent e) {
documentUpdated();
}
@Override
public void removeUpdate(DocumentEvent e) {
documentUpdated();
}
@Override
public void changedUpdate(DocumentEvent e) {
documentUpdated();
}
}
这将监视对Document
底层字段的更改,并调用您的fieldWasChanged
方法...
接下来,向此处理程序注册每个字段...
protected void registerDocumentHandler(JTextField field) {
DocumentHandler handler = new DocumentHandler(field);
field.getDocument().addDocumentListener(handler);
}
//...
registerDocumentHandler(txtBlue);
registerDocumentHandler(txtRed);
registerDocumentHandler(txtGreen);
现在,如果您实际尝试过此操作,您会发现键入内容的那一刻,您的UI会变得无响应,并且您的程序最终会因StackOverflowException
崩溃,这是因为DocumentHandler
正在更新JSlider
,后者正在更新字段,它会通知DocumentHandler
等等。
一个简单的解决方案是放入一个标志,而为true
阻止DocumentHandler
通知fieldWasChanged
方法...
public class DocumentHandler implements DocumentListener {
private JTextField field;
private boolean isUpdating;
public DocumentHandler(JTextField field) {
this.field = field;
}
protected void documentUpdated() {
if (!isUpdating) {
try {
fieldWasChanged(field);
} finally {
isUpdating = false;
}
}
}
//...
现在您可以键入并获取实时反馈,可以将文本粘贴到字段中,它们将更新滑块。
现在,说了这么多,我鼓励您尝试使用JFormattedTextField
或JSlider
而不是JTextField
因为它们可以帮助自己验证数据。 有关更多详细信息,请参见如何使用格式化的文本字段和如何使用微调框 。
如果您不想使用它们,但仍然希望限制用户只能输入数字,请查看实现文档过滤器和DocumentFilter示例
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.