如何覆盖 JColorChooser 重置按钮?

How to override JColorChooser Reset Button?

在之前的 post 中,我讨论了覆盖预览面板并且一切正常,只是出现了一个新问题,希望它的修复也一样简单。

这个新问题与重置按钮有关。根据文档,重置按钮会将颜色重置为传入的原始颜色。这很好用,但是如果有辅助字段怎么办?

这是代码...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class ColorChooserSample implements Runnable{

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

    private JPanel panel;
    JTextField counter;
    int vCounter = 1;

    @Override
    public void run() {
        JFrame frame = new JFrame(
                "JColorChooser Sample");
        frame.setDefaultCloseOperation(
                JFrame.EXIT_ON_CLOSE);

        panel = new JPanel();
        panel.setPreferredSize(new Dimension(300, 200));
        JButton button = new JButton(
                "Pick to Change JPanel Background");
        button.addActionListener(new ColorListener());
        panel.add(button);

        frame.add(panel, BorderLayout.CENTER);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public void setJPanelBackground(Color color) {
        panel.setBackground(color);
        panel.repaint();
    }

    public class ColorListener implements 
            ActionListener, ChangeListener {

        private JColorChooser chooser;

        private JPanel previewPanel;

        @Override
        public void actionPerformed(
                ActionEvent actionEvent) {
            Color backgroundColor = showDialog(panel, 
                    "Set JPanel Background", 
                    panel.getBackground());
            setJPanelBackground(backgroundColor);
        }

        private Color showDialog(Component component, 
                String title, Color initialColor) 
                        throws HeadlessException {
            chooser = new JColorChooser(initialColor);
            chooser.getSelectionModel()
                .addChangeListener(this);

            // configuring color chooser panel
            previewPanel = new JPanel();
            previewPanel.setBackground(initialColor);
            JLabel label = new JLabel("Hello World!");
            counter = new JTextField("0");
            previewPanel.add(label, BorderLayout.WEST);
            previewPanel.add(counter, BorderLayout.EAST);
            chooser.setPreviewPanel(previewPanel);

            // creating dialog
            ColorTracker ok = new ColorTracker(chooser);
            JDialog dialog = JColorChooser.createDialog(
                    component, title, true, chooser, 
                    ok, null);
            dialog.setVisible(true);
            return ok.getColor();
        }

        @Override
        public void stateChanged(ChangeEvent event) {
            Color newColor = chooser.getColor();
            previewPanel.setBackground(newColor);
            counter.setText(Integer.toString(vCounter++));
        }
    }

    private class ColorTracker implements ActionListener {

        private Color color;

        private JColorChooser chooser;

        public ColorTracker(JColorChooser chooser) {
            this.chooser = chooser;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            color = chooser.getColor();
        }

        public Color getColor() {
            return color;
        }

    }

}

以上代码会先打开这个对话框。

单击 "Pick to Change JPanelBackground" 按钮后,将打开带有修改后的预览部分的 JColorDialog。此部分包括将更改背景颜色的 "Hello World" 和一个计算颜色更改次数的计数器。

下面显示了最后选择的颜色,但还在文本框中显示了 5,表示单击了 5 个颜色选项。

点击重置按钮,颜色背景设置为原始颜色,但计数未重置回 0。

您可以为“确定”按钮和“取消”按钮传递监听器,但不能为“重置”按钮传递监听器。

这只是一个示例,因为“预览”部分可能还有其他项目。 objective 是如何重置颜色以外的值?

reset 按钮唯一做的事情就是调用 chooserPane.setColor(initialColor)。因此,如果您真正需要的是聆听颜色变化,您可以通过以下方式做到这一点:

        chooser.getSelectionModel().addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                Color newColor = chooser.getColor();
                previewPanel.setBackground(newColor);
                counter.setText(Integer.toString(vCounter++));
            }
        });

并且您的辅助面板得到更新。

话虽如此,如果您真的想为按钮添加一个侦听器,则没有公开的访问方式 - 您需要一直向下迭代组件,直到你找到按钮,然后给它添加一个监听器。

编辑 好的,所以它必须是重置按钮。由于这是某些内容创建方法的局部变量,因此必须通过手术将其删除。只需将 new JButton("abc") 更改为您自己的按钮,使用您自己的监听器。

        Locale locale = dialog.getLocale();
        String resetString = UIManager.getString("ColorChooser.resetText", locale);

        Container contentPane = dialog.getContentPane();
        JPanel buttonPanel = null;
        for (Component c : contentPane.getComponents()) {
            if (c instanceof JPanel) {
                buttonPanel = (JPanel) c;
            }
        }

        JButton resetButton = null;
        if (buttonPanel != null) {
            for (Component b : buttonPanel.getComponents()) {
                if (b instanceof JButton) {
                    JButton button = (JButton) b;
                    if (resetString.equals(button.getText())) {
                        resetButton = button;
                        break;
                    }
                }
            }
            if (resetButton != null) {
                buttonPanel.remove(resetButton);
                buttonPanel.add(new JButton("abc"));
            }
        }