gpt4 book ai didi

java - 为什么 JTextField.setText ("String") 在 DocumentListener 中不起作用?

转载 作者:行者123 更新时间:2023-12-01 12:03:27 26 4
gpt4 key购买 nike

我必须构建一个 GUI,它采用 4 个可着色形状(MyShape 类),这些形状一开始是灰色的。稍后,在 GUI 底部的三个 JTextField 上写入 RGB 值,我将能够设置新颜色,该颜色将绘制稍后单击的每张图片。

一切都很好,除了在 DocumentListener 中我不能使用 setText 方法,否则我会得到一个 IllegalStateException。我想调用该方法来纠正 RGB 分量的错误值:例如,如果用户写入 500,文本将自动将 JTextField 设置为 255。

这是完整项目的代码,以便您可以运行它(在代码中,我在有问题的方法之前注释了该行(我知道读起来有点长,谢谢您,如果您能帮助我)无论如何!:) ):

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.util.Arrays;
import java.util.List;

public class ShapesGUI extends JFrame {
private ShapesPlayGround shapesPlayGround;
private ColorPreview colorPreview;
private RGB rgb;
private List<MyShape> shapeList;

public ShapesGUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setLayout(new BorderLayout());
Container cnt = getContentPane();

shapesPlayGround = new ShapesPlayGround();
colorPreview = new ColorPreview();
rgb = new RGB();

cnt.add(shapesPlayGround, BorderLayout.CENTER);
cnt.add(colorPreview, BorderLayout.WEST);
cnt.add(rgb, BorderLayout.SOUTH);

pack();
setVisible(true);

}

public void setShapeList(List<MyShape> shapeList) {this.shapeList = shapeList;}

class ShapesPlayGround extends JPanel {
MyShape[] shapes;

public ShapesPlayGround() {
setPreferredSize(new Dimension(800, 450));
setBorder(new TitledBorder("Shapes"));

shapes = new MyShape[4];

shapes[0] = new MyShape(new Rectangle2D.Double(50, 250, 40, 180)); // Rettangolo, basso sinistra
shapes[1] = new MyShape(new Rectangle2D.Double(500, 100, 250, 250)); // Quadrato, estrema destra
shapes[2] = new MyShape(new Ellipse2D.Double(75, 50, 250, 120)); // Ellisse, alto sinistra
shapes[3] = new MyShape(new Ellipse2D.Double(310, 200, 230, 230)); // Cerchio, destra

setShapeList(Arrays.asList(shapes));
addMouseListener(new MyMouseListener());

}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;

for (MyShape shape : shapes) {
g2.setPaint(shape.getColor());
g2.fill(shape.getShape());

g2.setPaint(Color.black);
g2.draw(shape.getShape());

}
}

class MyMouseListener extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent e) {
Point p = new Point(e.getX(), e.getY());

if (shapeList != null) {

for (MyShape shape : shapes) {
if (shape.getShape().contains(p)) {
shape.setColor(rgb.getColor());

}
repaint();

}
}
}
}
}

class ColorPreview extends JPanel {
int[] rgbValue = new int[3];
JPanel panel;
Shape preview;

public ColorPreview() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(new JLabel(" Preview "));

panel = new JPanel();
panel.setBorder(new TitledBorder("Color"));

add(panel);

}

public void setColor(int[] rgbValue) {this.rgbValue = rgbValue;}
public int[] getColor() {return rgbValue;}

public void paintColor() {
Graphics2D g2 = (Graphics2D)getGraphics();

preview = new Rectangle2D.Double(panel.getX() + 5, panel.getY() + 20, panel.getWidth() - 10, panel.getWidth() - 10);

g2.setPaint(rgb.getColor());
g2.fill(preview);

}
}

class RGB extends JPanel {
private JPanel[] rgbPanel = new JPanel[3];
private String[] panelTitles = {"Red", "Green", "Blue"};
private JTextField[] rgbText = new JTextField[3];
private JTextField[] partialColor = new JTextField[3];
private Shape[] rgbShape;
private int[] rgbValue = new int[3];
private Color color;

public RGB() {
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

for (int i = 0; i < 3; i++) {
rgbPanel[i] = new JPanel();
rgbPanel[i].setLayout(new GridLayout(1, 2));
rgbPanel[i].setBorder(new TitledBorder(panelTitles[i]));

rgbText[i] = new JTextField();
partialColor[i] = new JTextField();

rgbValue[i] = 0;
rgbText[i].setText("0");

rgbText[i].getDocument().addDocumentListener(new TextChanged(i));

partialColor[i].setBackground(Color.black);
partialColor[i].setEditable(false);

rgbPanel[i].add(rgbText[i]);
rgbPanel[i].add(partialColor[i]);
add(rgbPanel[i]);

}

color = new Color(rgbValue[0], rgbValue[1], rgbValue[2]);

}

public int[] getRgbValue() {return rgbValue;}
public Color getColor() {return color;}

public void setRgbValue(int[] rgbValue) {this.rgbValue = rgbValue;}
public void setColor(Color color) {this.color = color;}

class TextChanged implements DocumentListener {
private int i;

public TextChanged(int i) {this.i = i;}

@Override
public void insertUpdate(DocumentEvent e) {listen(i);}

@Override
public void removeUpdate(DocumentEvent e) {listen(i);}

@Override
public void changedUpdate(DocumentEvent e) {listen(i);}

private int fixValue(int value) {return value < 0 ? 0 : (value > 255 ? 255 : value);}
// HERE'S THE PROBLEM!!!
private void listen(int i) {
try {
rgbValue[i] = fixValue(Integer.parseInt(rgbText[i].getText()));

} catch (NumberFormatException e) {
rgbValue[i] = 0;

}

color = new Color(rgbValue[0], rgbValue[1], rgbValue[2]);
rgb.setColor(color);
colorPreview.paintColor();

try {
rgbText[i].setText("" + rgbValue[i]);

} catch (IllegalStateException e) {
System.out.println("~Shit, Exception");

}

if (i == 0) partialColor[0].setBackground(new Color(rgbValue[0], 0, 0));
else if (i == 1) partialColor[1].setBackground(new Color(0, rgbValue[1], 0));
else if (i == 2) partialColor[2].setBackground(new Color(0, 0, rgbValue[2]));

}
}
}

public static void main(String args[]) {
new ShapesGUI();

}

}

最佳答案

一种可能的解决方案是将您对文本的更改包装在 Runnable 中,并使用 SwingUtilitiles.invokeLater(yourRunnable) 将其在事件线程上排队,但也许更好......尝试在输入完全注册到文本组件中之前更正输入。在这种情况下,不要使用 DocumentListener,而应使用 DocumentFilter。

更好 - 使用 JSlider 或 JSpinner

例如,

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.EnumMap;
import java.util.Map;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class SpinnerEg extends JPanel {
private Map<RGB, JSlider> sliderMap = new EnumMap<>(RGB.class);
private JPanel displayPanel = new JPanel();
private Color displayPanelColor = new Color(0, 0, 0);

public SpinnerEg() {
displayPanel.setBackground(displayPanelColor);
JPanel sliderPanel = new JPanel(new GridLayout(1, 0));
for (RGB rgb : RGB.values()) {
createRgbSlider(sliderPanel, rgb);
}

displayPanel.setPreferredSize(new Dimension(400, 400));

setLayout(new BorderLayout());
add(displayPanel);
add(sliderPanel, BorderLayout.PAGE_END);
}

private void createRgbSlider(JPanel sliderPanel, final RGB rgb) {
final JSlider slider = new JSlider(0, 255, 0);
slider.setMajorTickSpacing(50);
slider.setPaintLabels(true);
slider.setPaintTicks(true);
sliderMap.put(rgb, slider);

slider.addChangeListener(new ChangeListener() {

@Override
public void stateChanged(ChangeEvent e) {
int red = sliderMap.get(RGB.RED).getValue();
int green = sliderMap.get(RGB.GREEN).getValue();
int blue = sliderMap.get(RGB.BLUE).getValue();
displayPanelColor = new Color(red, green, blue);
displayPanel.setBackground(displayPanelColor);
}
});

JPanel rgbPanel = new JPanel(new BorderLayout());
rgbPanel.setBorder(BorderFactory.createTitledBorder(rgb.getName()));
rgbPanel.add(slider);

sliderPanel.add(rgbPanel);
}

private static void createAndShowGui() {
SpinnerEg mainPanel = new SpinnerEg();

JFrame frame = new JFrame("SpinnerEg");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

enum RGB {
RED("Red", Color.red), GREEN("Green", Color.green), BLUE("Blue", Color.blue);
private String name;
private Color color;

private RGB(String name, Color color) {
this.name = name;
this.color = color;
}

public String getName() {
return name;
}

public Color getColor() {
return color;
}

}

关于java - 为什么 JTextField.setText ("String") 在 DocumentListener 中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27846792/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com