我目前正在GUI中设计一个图像编辑器,它有几个按钮,点击它们时,应该对加载的图像应用不同的效果。我的效果与ActionListener
一起使用但是如果我在单击另一个效果后尝试单击效果,则图像变为黑色而不是应用所需的效果。如何将多个效果应用于同一图像?这是我的ButtonPanel
类的代码,其中包含ActionListener
和效果代码(目前只实现了三种效果):
class ButtonPanel extends JPanel
{
//JButton makeBlue;
BufferedImage img;
ImagePanel ip = new ImagePanel();
ButtonPanel(ImagePanel x)
{
final JButton makeBlue = new JButton ("Make Blue");
final JButton makeRed = new JButton ("Make Red");
final JButton makeGreen = new JButton ("Make Green");
final JButton invertColors = new JButton ("Invert Colors");
final JButton makeGreyscale = new JButton ("Greyscale");
final JButton makeWarhol = new JButton ("Warhol");
final JButton flipVertical = new JButton ("Flip Vertical");
final JButton flipHorizontal = new JButton ("Flip Horizontal");
final JButton rotateClockwise = new JButton ("Rotate Clockwise");
setBackground(Color.RED);
ip = x;
//int width, height;
//setBackground(Color.RED);
//int height = 0;
add(makeBlue);
add(makeRed);
add(makeGreen);
add(invertColors);
add(makeGreyscale);
add(makeWarhol);
add(flipVertical);
add(flipHorizontal);
add(rotateClockwise);
ActionListener action =
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
BufferedImage img = ip.getImg();
if (e.getSource()== makeBlue)
{
int width = img.getWidth(); //# of pixel columns
int height = img.getHeight(); //# of pixels rows
for(int i=0; i<width;i++)
{
for(int j=0; j<height; j++)
{
int value = img.getRGB(i,j);
int y = 0xFF0000FF;
value = value & y;
img.setRGB(i,j,value);
}
}
ip.setImage(img);
setBackground(Color.GREEN);
repaint();
}
else if(e.getSource()== makeRed)
{
int width = img.getWidth(); //# of pixel columns
int height = img.getHeight(); //# of pixels rows
for(int i=0; i<width;i++)
{
for(int j=0; j<height; j++)
{
//fill in code here
int value = img.getRGB(i,j);
int y = 0xFFFF0000;
value = value & y;
//System.out.println(value);
img.setRGB(i,j,value);
}
}
ip.setImage(img);
repaint();
}
else if(e.getSource()== makeGreen)
{
int width = img.getWidth(); //# of pixel columns
int height = img.getHeight(); //# of pixels rows
for(int i=0; i<width;i++)
{
for(int j=0; j<height; j++)
{
//fill in code here
int value = img.getRGB(i,j);
int y = 0xFF00FF00;
value = value & y;
img.setRGB(i,j,value);
}
}
ip.setImage(img);
repaint();
}
}
};
makeBlue.addActionListener(action);
makeRed.addActionListener(action);
makeGreen.addActionListener(action);
makeWarhol.addActionListener(action);
flipVertical.addActionListener(action);
flipHorizontal.addActionListener(action);
rotateClockwise.addActionListener(action);
makeGreyscale.addActionListener(action);
invertColors.addActionListener(action);
}
}
任何帮助将不胜感激。感谢。
答案 0 :(得分:2)
您的问题是,您要从图像中提取所有一种颜色,然后用新提取的图像替换ImagePanel中的原始图像,也就是说,如果按下绿色按钮,则全部为绿色。然后,当您尝试从ImagePanel的图像中提取红色时,您将全黑,因为图像现在只是绿色。
如果要提取原始颜色,则需要将原始图像保存在某处。也许你应该给ImagePanel一个方法,getOriginalImage()
或其他一些方法,并让它存储两个图像,一个是显示的图像,另一个是更改的图像。
更好的是,使用模型 - 视图 - 控制模式并将图像存储在GUI之外的其他位置。
答案 1 :(得分:2)
有两种方法可以实现这一目标。您可以将您的类设置为ActionListener(这是您现在设置它的方式),也可以为每个按钮设置一个唯一的ActionListener。作为一个设计决策,我更喜欢后者,因为你可以通过这种方式获得更精确的控制和更容易阅读的代码。
每个按钮,菜单项以及任何其他想要具有独特效果的对象都应该拥有自己的ActionListener。您可以为每个ActionListener,内部类或每个的匿名内部类编写新的类文件。我更喜欢按照你的构造函数或设置方法放置的匿名内部类:
JButton testButton = new JButton("Test");
testButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
// do stuff here
System.out.println("You clicked me!");
}
});
此方法允许您忽略巨大的条件分支和不必要的比较。为需要侦听器的每个组件唯一地实现接口。