JColorChooser return 之前选择的颜色
JColorChooser return previously chosen color
我正在 Java 中开发一个简单的绘图应用程序,当我选择一种颜色时,按钮背景会完全改变,但返回的颜色始终是以前的颜色。
例如,如果我选择黑色然后选择蓝色,它会涂成 black.And 如果我在蓝色之后选择另一种颜色,它会涂成蓝色。
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();
}
}
问题在于 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
这意味着首先调用用于 "get" 来自按钮的 selected 颜色的 ActionListener
,在实际用于 [=] 的 ActionListener
之前31=] 颜色
一个可能的解决方案是使用 PropertyChangeListener
并在 selectedColor
更改时触发 propertyChanged
事件,例如...
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);
}
}
}
}
我正在 Java 中开发一个简单的绘图应用程序,当我选择一种颜色时,按钮背景会完全改变,但返回的颜色始终是以前的颜色。
例如,如果我选择黑色然后选择蓝色,它会涂成 black.And 如果我在蓝色之后选择另一种颜色,它会涂成蓝色。
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();
}
}
问题在于 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
这意味着首先调用用于 "get" 来自按钮的 selected 颜色的 ActionListener
,在实际用于 [=] 的 ActionListener
之前31=] 颜色
一个可能的解决方案是使用 PropertyChangeListener
并在 selectedColor
更改时触发 propertyChanged
事件,例如...
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);
}
}
}
}