我有一个家庭作业,我必须改变颜色选择器(它有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。关于解决方案的任何想法?
谢谢!
答案 0 :(得分:1)
创建一个可以处理已更改字段的方法......
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);
现在,如果你真的试过这个,你会发现你输入内容的那一刻,你的用户界面会变得没有响应,你的程序最终会因StackOverflowException
而崩溃,这是因为DocumentHandler
正在更新JSlider
s,这是更新字段,通知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
,因为它们可以帮助验证数据本身。有关详细信息,请参阅How to Use Formatted Text Fields和How to Use Spinners。
如果您不想使用这些内容,但仍希望限制用户只能输入数字,请查看Implementing a Document Filter和DocumentFilter Examples