【问题标题】:JColorChooser return previously chosen colorJColorChooser 返回先前选择的颜色
【发布时间】:2016-07-15 11:47:27
【问题描述】:

我正在使用 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();

}

}

【问题讨论】:

  • 可能是线程问题?使您的颜色变量volatile 并重试。不确定,它有效...
  • 我试过了,还是一样的问题。
  • 那么您还必须在代码中显示您使用颜色变量进行绘画的位置。显示的代码似乎没问题。
  • 什么是 DrawArea?它是如何工作的?
  • 添加一些 System.out.println 语句来跟踪你的动作监听器被触发的顺序

标签: java jcolorchooser


【解决方案1】:

问题在于通知ActionListener 的顺序。通常,Swing 调用按 LIFO 顺序监听

所以,使用下面的代码,加上一些额外的System.outs...

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 并在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);
            }
        }

    }
}

【讨论】:

  • 谢谢它有很大帮助
猜你喜欢
  • 2016-02-02
  • 2022-01-22
  • 2016-02-08
  • 2019-09-25
  • 1970-01-01
  • 1970-01-01
  • 2021-04-03
  • 2014-01-06
  • 2020-01-19
相关资源
最近更新 更多