我正在使用Java编写一个简单的绘图应用程序,当我选择一种颜色时,按钮背景会完美变化,但返回的颜色始终是前一种颜色。
例如,如果我选择黑色然后选择蓝色,它将涂成黑色。如果我在蓝色后选择另一种颜色,它将以蓝色绘制。
public class ColorChooserBtn extends JButton {
private Color color;
public ColorChooserBtn() {
super();
this.setBackground(Color.BLACK);
this.setPreferredSize(new Dimension(16, 16));
this.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
Color c = JColorChooser.showDialog(null, "Choose a Color", color);
if (c != null){
setSelectedColor(c);
setBackground(color);
}
}
});
}
public Color getSelectedColor() {
return color;
}
public void setSelectedColor(Color newColor) {
color = newColor;
}
}
public class Paint {
DrawArea drawArea;
JButton clearBtn;
ColorChooserBtn colorBtn;
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == clearBtn){
drawArea.clear();
} else if(e.getSource() == colorBtn){
drawArea.coloring(colorBtn.getSelectedColor());
}
}
};
public Paint() {
JFrame frame = new JFrame("Paint");
frame.getContentPane().setLayout(new BorderLayout());
drawArea = new DrawArea();
frame.getContentPane().add(drawArea, BorderLayout.CENTER);
JPanel controls = new JPanel();
clearBtn = new JButton("Clear");
clearBtn.addActionListener(actionListener);
colorBtn = new ColorChooserBtn();
colorBtn.addActionListener(actionListener);
controls.add(clearBtn);
controls.add(colorBtn);
frame.getContentPane().add(controls,BorderLayout.NORTH);
frame.setSize(600, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
new Paint();
}
}
答案 0 :(得分:1)
问题是通知ActionListener
的顺序。通常,Swing调用以LIFO顺序监听
因此,使用以下代码,以及一些额外的System.out
s ...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
ColorChooserBtn btn = new ColorChooserBtn();
add(btn);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Get color");
System.out.println(btn.getSelectedColor());
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class ColorChooserBtn extends JButton {
private Color color;
public ColorChooserBtn() {
super();
this.setBackground(Color.BLACK);
this.setPreferredSize(new Dimension(16, 16));
this.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Choose color");
Color c = JColorChooser.showDialog(null, "Choose a Color", color);
if (c != null) {
setSelectedColor(c);
setBackground(color);
}
}
});
}
public Color getSelectedColor() {
return color;
}
public void setSelectedColor(Color newColor) {
color = newColor;
}
}
}
...打印
Get color
null
Choose color
这意味着,在用于实际选择颜色的ActionListener
之前,首先调用用于“获取”按钮中所选颜色的ActionListener
一种可能的解决方案可能是使用PropertyChangeListener
并在更改propertyChanged
时触发selectedColor
事件,例如......
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
ColorChooserBtn btn = new ColorChooserBtn();
add(btn);
btn.addPropertyChangeListener("selectedColor", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("Changed");
System.out.println(evt.getNewValue());
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class ColorChooserBtn extends JButton {
private Color color;
public ColorChooserBtn() {
super();
this.setBackground(Color.BLACK);
this.setPreferredSize(new Dimension(16, 16));
this.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Choose color");
Color c = JColorChooser.showDialog(null, "Choose a Color", color);
if (c != null) {
setSelectedColor(c);
setBackground(color);
}
}
});
}
public Color getSelectedColor() {
return color;
}
public void setSelectedColor(Color newColor) {
if (newColor != color) {
Color oldColor = color;
color = newColor;
firePropertyChange("selectedColor", oldColor, newColor);
}
}
}
}