【问题标题】:How to override JColorChooser Reset Button?如何覆盖 JColorChooser 重置按钮?
【发布时间】:2020-09-17 10:07:39
【问题描述】:

在上一篇文章中,我讨论了覆盖预览面板,一切都运行良好,除了出现了一个新问题并希望修复它同样简单。

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

这里是代码...

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。

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

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

【问题讨论】:

    标签: java colors jcolorchooser


    【解决方案1】:

    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"));
                }
            }
    

    【讨论】:

    • Reset 的颜色变化确实会触发该调用,但仍需要区分是通过实际颜色变化还是 Reset 调用,以确定增加或重置计数器。
    • 我会尝试上面的代码,但实际上是来这里发布的,我确实迭代了所有组件以精确定位重置按钮并添加了我自己的侦听器并且它有效。当然,担心名称是否会改变。
    • 好的,我明白你做了什么。很好地确保检索到正确的按钮名称/标签。
    • 新代码可以工作并且能够添加我自己的按钮。唯一的问题是默认功能丢失。现在单击重置可以满足我的要求,但不会重置其他选项卡。
    • 我添加的一件事是通过克隆复制重置操作侦听器,然后将它们全部添加到我的新按钮中,然后再添加一个操作侦听器来执行我想要的操作。这似乎现在也处理了默认功能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 1970-01-01
    • 2016-10-14
    相关资源
    最近更新 更多