Цветной jcombobox с цветными элементами и фокусом - PullRequest
3 голосов
/ 07 февраля 2012

Я пытаюсь создать цветной выпадающий список с цветными элементами (см. Код ниже).Цвет применяется после того, как выпадающий список теряет фокус.

это правильное поведение?

как я могу изменить цвет переднего плана и / или фона, когда поле со списком имеет фокус?*

Ответы [ 3 ]

4 голосов
/ 07 февраля 2012

Вот еще один подход:

//JList#setSelectionForeground(...) version
static class ColoredCellRenderer implements ListCellRenderer {
  protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
  private final Color selectionBackground = new Color(240,200,200);
  public Component getListCellRendererComponent(
      JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    Color fgc = Colors.valueOf((String)value).color;
    if(index<0) {
      //comboBox.setForeground(fgc); //Windows, CDE/Motif Look & Feel
      list.setSelectionForeground(fgc);
      list.setSelectionBackground(selectionBackground);
    }
    JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(
        list, value, index, isSelected, cellHasFocus);
    if (index != -1) {
      renderer.setForeground(fgc);
    }
    return renderer;
  }
}

//html version
static class ComboHtmlRenderer extends DefaultListCellRenderer {
  private final Color selectionBackground = new Color(240,200,200);
  @Override public Component getListCellRendererComponent(
      JList list, Object value, int index, boolean isSelected, boolean hasFocus) {
    Color fgc = Colors.valueOf((String)value).color;
    if(index<0) {
      list.setSelectionBackground(selectionBackground);
    }
    JLabel l = (JLabel)super.getListCellRendererComponent(
                 list, value, index, isSelected, hasFocus);
    l.setText("<html><font color="+hex(fgc)+">"+value);
    l.setBackground(isSelected?selectionBackground:list.getBackground());
    return l;
  }
  private static String hex(Color c) {
    return String.format("#%06x", c.getRGB()&0xffffff);
  }
}
4 голосов
/ 07 февраля 2012

Пожалуйста, разделите Editor и Renderer и добавьте в DefaultListCellRenderer эти два метода

  • cellHasFocus

  • IsSelected

пример

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.event.EventListenerList;

class ColorComboBoxEditor1 implements ComboBoxEditor {

    final protected JLabel editor;
    //final protected JButton editor;
    private EventListenerList listenerList = new EventListenerList();

    ColorComboBoxEditor1(Color initialColor) {
        editor = new JLabel("");
        /*editor = new JButton("");
        editor.setBackground(initialColor);
        ActionListener actionListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Color currentBackground = editor.getBackground();
                Color color = JColorChooser.showDialog(editor, "Color Chooser", currentBackground);
                if ((color != null) && (currentBackground != color)) {
                    //editor.setBackground(color);
                    editor.setForeground(color);
                    fireActionEvent(color);
                }
            }
        };
        editor.addActionListener(actionListener);*/
    }

    @Override
    public void addActionListener(ActionListener l) {
        listenerList.add(ActionListener.class, l);
    }

    @Override
    public Component getEditorComponent() {
        return editor;
    }

    @Override
    public Object getItem() {
        return editor.getBackground();
    }

    @Override
    public void removeActionListener(ActionListener l) {
        listenerList.remove(ActionListener.class, l);
    }

    @Override
    public void selectAll() {
    }

    @Override
    public void setItem(Object newValue) {
        if (newValue instanceof Color) {
            Color color = (Color) newValue;
            //editor.setBackground(color);
            editor.setForeground(color);
            editor.setText(String.valueOf(newValue));
        } else {
            try {
                Color color = Color.decode(newValue.toString());
                //editor.setBackground(color);
                editor.setForeground(color);
                editor.setText(String.valueOf(newValue));
            } catch (NumberFormatException e) {
            }
        }
    }

    protected void fireActionEvent(Color color) {
        Object listeners[] = listenerList.getListenerList();
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i] == ActionListener.class) {
                ActionEvent actionEvent = new ActionEvent(editor, ActionEvent.ACTION_PERFORMED, color.toString());
                ((ActionListener) listeners[i + 1]).actionPerformed(actionEvent);
            }
        }
    }
}

class ColorCellRenderer1 implements ListCellRenderer {

    private DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
    // Width doesn't matter as the combo box will size
    private final static Dimension preferredSize = new Dimension(0, 20);

    @Override
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        if (value instanceof Color) {
            //renderer.setBackground((Color) value);
            renderer.setBackground(Color.white);
            renderer.setForeground((Color) value);
        }
        if (cellHasFocus || isSelected) {
            renderer.setBorder(new LineBorder(Color.DARK_GRAY));
        } else {
            renderer.setBorder(null);
        }
        renderer.setPreferredSize(preferredSize);
        return renderer;
    }
}

class ColorComboBoxEditorRendererDemo1 {

    public ColorComboBoxEditorRendererDemo1() {
        Color colors[] = {Color.BLACK, Color.BLUE, Color.GREEN, Color.RED, Color.WHITE, Color.YELLOW};
        JFrame frame = new JFrame("Color JComboBox");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JComboBox comboBox = new JComboBox(colors);
        comboBox.setEditable(true);
        comboBox.setRenderer(new ColorCellRenderer1());
        Color color = (Color) comboBox.getSelectedItem();
        ComboBoxEditor editor = new ColorComboBoxEditor1(color);
        comboBox.setEditor(editor);
        frame.add(comboBox, BorderLayout.NORTH);
        final JLabel label = new JLabel();
        label.setOpaque(true);
        label.setBackground((Color) comboBox.getSelectedItem());
        frame.add(label, BorderLayout.CENTER);
        ActionListener actionListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                Color selectedColor = (Color) comboBox.getSelectedItem();
                label.setBackground(selectedColor);
            }
        };
        comboBox.addActionListener(actionListener);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                ColorComboBoxEditorRendererDemo1 cCBERD1 = new ColorComboBoxEditorRendererDemo1();
            }
        });
    }
}
2 голосов
/ 07 февраля 2012

Цвет текста на переднем плане в вашем примере, кажется, работает правильно.Некоторые другие цвета управляются делегатом пользовательского интерфейса компонента для данного внешнего вида, как показано ниже.Обратите внимание, что делегат может выбрать применение цвета таким образом, чтобы сохранить контраст в различных состояниях, например, выбрано, включено и т. Д. Вы можете узнать больше в статье UIManager по умолчанию .

public static void main(String[] args) {
    UIManager.put("ComboBox.background", new ColorUIResource(Color.lightGray));
    UIManager.put("ComboBox.selectionBackground", new ColorUIResource(Color.magenta));
    UIManager.put("ComboBox.selectionForeground", new ColorUIResource(Color.yellow));
    javax.swing.SwingUtilities.invokeLater(new Runnable() {

        @SuppressWarnings("synthetic-access")
        public void run() {
            createAndShowGUI();
        }
    });
}
...