Java 7 JColorChooser:禁用透明度滑块

时间:2012-08-19 13:16:08

标签: java swing transparency java-7 jcolorchooser

JDK 7为JColorChooser添加了一个新的透明度滑块:

enter image description here

问题在于我不想让我的用户选择透明色。不幸的是,似乎没有一种简单的方法来禁用滑块。

摆脱透明度的一种方法是根据所选颜色创建一种新颜色,但删除alpha值。然而,这给用户留下了错误的印象,因为滑块现在实际上什么都不做,我讨厌有一个无用的UI元素。

所以我的问题是,摆脱透明度滑块的最佳方法是什么?

P.S。:IMO,他们只是添加滑块并使其成为默认行为,这很奇怪。这可能会导致JDK 6程序中的许多错误,这些错误不希望颜色选择器返回带有alpha值的颜色。

5 个答案:

答案 0 :(得分:4)

根据文档,可以只修改/配置现有的类。因此,建议的方法是创建自己的ChooserPanel(他们需要扩展AbstractColorChooserPanel),然后调用

JColorChooser jc = new JColorChooser();
jc.setChooserPanels(new AbstractColorChooserPanel[]{yourChooserPanel});

或者,如果您正在寻找更快/更凶悍/更丑陋的方式,请为您写下:

private static void removeTransparencySlider(JColorChooser jc) throws Exception {

    AbstractColorChooserPanel[] colorPanels = jc.getChooserPanels();
    for (int i = 1; i < colorPanels.length; i++) {
        AbstractColorChooserPanel cp = colorPanels[i];

        Field f = cp.getClass().getDeclaredField("panel");
        f.setAccessible(true);

        Object colorPanel = f.get(cp);
        Field f2 = colorPanel.getClass().getDeclaredField("spinners");
        f2.setAccessible(true);
        Object spinners = f2.get(colorPanel);

        Object transpSlispinner = Array.get(spinners, 3);
        if (i == colorPanels.length - 1) {
            transpSlispinner = Array.get(spinners, 4);
        }
        Field f3 = transpSlispinner.getClass().getDeclaredField("slider");
        f3.setAccessible(true);
        JSlider slider = (JSlider) f3.get(transpSlispinner);
        slider.setEnabled(false);
        Field f4 = transpSlispinner.getClass().getDeclaredField("spinner");
        f4.setAccessible(true);
        JSpinner spinner = (JSpinner) f4.get(transpSlispinner);
        spinner.setEnabled(false);
    }
}

祝你好运:)

答案 1 :(得分:3)

虽然它依赖于实现,但您可以按名称删除AbstractColorChooserPanel的具体子类。

此示例删除除RGB面板之外的所有内容:

AbstractColorChooserPanel[] ccPanels = chooser.getChooserPanels();
for (AbstractColorChooserPanel ccPanel : ccPanels) {
    System.out.println(ccPanel.getDisplayName());
    String name = ccPanel.getClass().getSimpleName();
    if (!"DefaultRGBChooserPanel".equals(name))
        tcc.removeChooserPanel(ccPanel);
}

此示例恢复HSB面板:

for (AbstractColorChooserPanel ccPanel : ccPanels) {
    String name = ccPanel.getClass().getSimpleName();
    if ("DefaultHSBChooserPanel".equals(name))
        tcc.addChooserPanel(ccPanel);
}

您需要根据经验确定所需的名称。

答案 2 :(得分:1)

以下是对aymeric的答案的略微修改,完全隐藏它们而不是禁用它们。

private static void removeTransparencySlider(JColorChooser jc) throws Exception {

    AbstractColorChooserPanel[] colorPanels = jc.getChooserPanels();
    for (int i = 1; i < colorPanels.length; i++) {
        AbstractColorChooserPanel cp = colorPanels[i];

        Field f = cp.getClass().getDeclaredField("panel");
        f.setAccessible(true);

        Object colorPanel = f.get(cp);
        Field f2 = colorPanel.getClass().getDeclaredField("spinners");
        f2.setAccessible(true);
        Object spinners = f2.get(colorPanel);

        Object transpSlispinner = Array.get(spinners, 3);
        if (i == colorPanels.length - 1) {
            transpSlispinner = Array.get(spinners, 4);
        }
        Field f3 = transpSlispinner.getClass().getDeclaredField("slider");
        f3.setAccessible(true);
        JSlider slider = (JSlider) f3.get(transpSlispinner);
        slider.setEnabled(false);
        slider.setVisible(false);
        Field f4 = transpSlispinner.getClass().getDeclaredField("spinner");
        f4.setAccessible(true);
        JSpinner spinner = (JSpinner) f4.get(transpSlispinner);
        spinner.setEnabled(false);
        spinner.setVisible(false);

        Field f5 = transpSlispinner.getClass().getDeclaredField("label");
        f5.setAccessible(true);
        JLabel label = (JLabel) f5.get(transpSlispinner);
        label.setVisible(false);
    }
}

答案 3 :(得分:1)

此处的其他答案显示了如何从JColorChooser实例中删除透明度滑块,但使用JColorChooser的主要方法是静态showDialog方法,在这种情况下,您无法访问实例。因此,我提出了两种方法,一种是隐藏JColorChooser实例的控件,另一种是showDialog的替换方法,它有showTransparencyControls作为额外参数:

import java.awt.*;
import java.awt.event.ActionListener;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.*;
import javax.swing.colorchooser.AbstractColorChooserPanel;

class SwingUtil {
    /**
     * Hides controls for configuring color transparency on the specified
     * color chooser.
     */
    public static void hideTransparencyControls(JColorChooser cc) {
        AbstractColorChooserPanel[] colorPanels = cc.getChooserPanels();
        for (int i = 0; i < colorPanels.length; i++) {
            AbstractColorChooserPanel cp = colorPanels[i];
            try {
                Field f = cp.getClass().getDeclaredField("panel");
                f.setAccessible(true);
                Object colorPanel = f.get(cp);

                Field f2 = colorPanel.getClass().getDeclaredField("spinners");
                f2.setAccessible(true);
                Object sliders = f2.get(colorPanel);

                Object transparencySlider = java.lang.reflect.Array.get(sliders, 3);
                if (i == colorPanels.length - 1)
                    transparencySlider = java.lang.reflect.Array.get(sliders, 4);

                Method setVisible = transparencySlider.getClass().getDeclaredMethod(
                    "setVisible", boolean.class);
                setVisible.setAccessible(true);
                setVisible.invoke(transparencySlider, false);
            } catch (Throwable t) {}
        }
    }


    /**
     * Shows a modal color chooser dialog and blocks until the dialog is
     * closed.
     * 
     * @param component the parent component for the dialog; may be null
     * @param title the dialog's title
     * @param initialColor the initial color set when the dialog is shown
     * @param showTransparencyControls whether to show controls for
     *        configuring the color's transparency
     * @return the chosen color or null if the user canceled the dialog
     */
    public static Color showColorChooserDialog(Component component,
            String title, Color initialColor, boolean showTransparencyControls) {
        JColorChooser pane = new JColorChooser(
            initialColor != null ? initialColor : Color.white);
        if (!showTransparencyControls) hideTransparencyControls(pane);
        Color[] result = new Color[1];
        ActionListener okListener = e -> result[0] = pane.getColor();
        JDialog dialog = pane.createDialog(component, title, true, pane, okListener, null);
        dialog.setVisible(true);
        dialog.dispose();
        return result[0];
    }
}

答案 4 :(得分:0)

Java 9 adds一个新属性public void setColorTransparencySelectionEnabled(boolean b); public boolean isColorTransparencySelectionEnabled(); 来控制这些滑块:

JColorChooser.showDialog

静态public static Color showDialog(Component component, String title, Color initialColor, boolean colorTransparencySelectionEnabled); 方法还有一个新的重载来指定相同的属性:

$link1 = "https://mbasic.facebook.com/TrendingInPhilippinesOfficial/videos/1722369168023859/";
$link2 = "https://mbasic.facebook.com/story.php?story_fbid=1722369168023859&id=1388211471439632";
$regex = '/(videos|story_fbid)(\/|=)(\d+)(\/|&)?/';

preg_match($regex, $link1, $matches);
preg_match($regex, $link2, $matches2);

2017年3月,Java 9为expected to be released