2017-04-26 1 views
0

Mise à jour Questionpersonnalisée couleur de fond de changement JComboBoxRenderer selon la sélection de texte

Partie 1: A l'origine, j'ai été va supprimer la sélection en surbrillance après un élément a été sélectionné (parce que c'était chambouler l'arrière-plan couleur pour la sélection faite). J'ai vu cela pourrait se faire d'ici>Delete highlighting in JComboBox - (Résolu)

Partie 2: maintenant ... Je suis en train de faire identifier le texte sélectionné et changer la couleur d'arrière-plan (lorsqu'il est sélectionné, et non lorsque la souris survole l'élément de la liste) en fonction du texte sélectionné. Il fait changer la couleur pour correspondre au texte, mais lorsque vous sélectionnez un objet (désélectionnant la combobox), les changements de couleur de fond aux paramètres par défaut - (Résolus - Voir ma solution)

Partie 3: De plus, j'aimerais que la couleur d'arrière-plan apparaisse pour le texte dans la liste déroulante (alors que la souris n'est pas survolée). - (Résolu)

Voici le code ...

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

class ComboBoxRenderer extends JLabel implements ListCellRenderer 
{ 
    private Color selectionBackgroundColor; 
    private DefaultListCellRenderer dlcr = new DefaultListCellRenderer(); 

    // Constructor 
    public ComboBoxRenderer() 
    { 
     setOpaque(true); 
     setHorizontalAlignment(CENTER); 
     setVerticalAlignment(CENTER); 
     selectionBackgroundColor = this.dlcr.getBackground(); // Have to set a color, else a compiler error will occur 
    } 

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) 
    { 
     // Set the list background color to default color (default color will show once selection is made) 
     setBackground(list.getBackground()); 
     Color mouseHoverHighlight = Color.LIGHT_GRAY; 
     setText((String)value); 

     // Check which item is selected 
     if(isSelected) 
     { 
      // Set background color of the item your cursor is hovering over to the original background color 
      setBackground(mouseHoverHighlight); 
     } 
     else 
     { 
      // Set background to specific color depending on text value 
      String selectedTextInDropdownList = getText(); 
      if (selectedTextInDropdownList.equals("SelectedTextOne")) { 
       setBackground(Color.GREEN); 
      } else if (selectedTextInDropdownList.equals("SelectedTextTwo")) { 
       setBackground(Color.RED); 
      } 
     } 
     String selectedText = getText(); 
     if (selectedText.equals("SelectedTextOne")){ 
      list.setSelectionBackground(Color.GREEN); 
     } else if (selectedText.equals("SelectedTextTwo")){ 
      list.setSelectionBackground(Color.RED); 
     } else { 
      list.setSelectionBackground(this.dlcr.getBackground()); 
     } 

     return this; 
    } 
} 

Edit: aussi ... Voici le code à une interface graphique du tambour afin que vous puissiez voir comment il se comporte. ..

Edit2: Code modifié pour compiler sans arrière-plan montré dans les images

import org.apache.commons.lang3.ArrayUtils; 

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 

import javax.imageio.ImageIO; 
import javax.swing.*; 
import javax.swing.border.Border; 
import javax.swing.border.TitledBorder; 
import javax.swing.plaf.ColorUIResource; 
import javax.swing.plaf.metal.MetalComboBoxButton; 

public class TestGui extends JFrame { 
    private final String[] guiCharSelDefault = {"--- Select Character ---"}; 
    private final String[] characters = {"SelectedTextOne", "SelectedTextTwo", "SelectedTextThree", "SelectedTextFour"}; 
    private final String[] guiCharSel = (String[]) ArrayUtils.addAll(guiCharSelDefault, characters); 
    private JComboBox charCombo = createStandardCombo(guiCharSel); 
    private JPanel topFrame = createTopFrame(); 
    private JScrollPane topFrameScroll = createTopScrollPane(); 
    private JPanel centerFrame = createCenterFrame(); 

    //************************************************************************************** 
    // Constructor 

    TestGui(){ 
     add(topFrameScroll, BorderLayout.NORTH); 
     add(centerFrame, BorderLayout.CENTER); 

     setSize(800,600); 
     setVisible(true); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    //************************************************************************************** 
    // Support Methods 
    private static GridBagConstraints setGbc(int gridx, int gridy, int gridWidth, int gridHeight, int ipadx, int ipady, String anchorLocation, double weightx, double weighty, Insets insets){ 
     GridBagConstraints gbc = new GridBagConstraints(); 

     if (anchorLocation.toUpperCase().equals("NORTHWEST")){ 
      gbc.anchor = GridBagConstraints.NORTHWEST; 
     } else if (anchorLocation.toUpperCase().equals("NORTH")){ 
      gbc.anchor = GridBagConstraints.NORTH; 
     } else if (anchorLocation.toUpperCase().equals("NORTHEAST")){ 
      gbc.anchor = GridBagConstraints.NORTHEAST; 
     } else if (anchorLocation.toUpperCase().equals("WEST")){ 
      gbc.anchor = GridBagConstraints.WEST; 
     } else if (anchorLocation.toUpperCase().equals("EAST")){ 
      gbc.anchor = GridBagConstraints.EAST; 
     } else if (anchorLocation.toUpperCase().equals("SOUTHWEST")){ 
      gbc.anchor = GridBagConstraints.SOUTHWEST; 
     } else if (anchorLocation.toUpperCase().equals("SOUTH")){ 
      gbc.anchor = GridBagConstraints.SOUTH; 
     } else if (anchorLocation.toUpperCase().equals("SOUTHEAST")){ 
      gbc.anchor = GridBagConstraints.SOUTHEAST; 
     } else { 
      gbc.anchor = GridBagConstraints.CENTER; 
     } 

     gbc.gridx = gridx; // column 
     gbc.gridy = gridy; // row 
     gbc.gridwidth = gridWidth; // number of columns 
     gbc.gridheight = gridHeight; // number of rows 
     gbc.ipadx = ipadx; // width of object 
     gbc.ipady = ipady; // height of object 
     gbc.weightx = weightx; // shifts rows to side of set anchor 
     gbc.weighty = weighty; // shifts columns to side of set anchor 
     gbc.insets = insets; // placement inside cell 
     gbc.fill = GridBagConstraints.HORIZONTAL; 
     gbc.fill = GridBagConstraints.VERTICAL; 

     return gbc; 
    } 

    private Insets setInsets(int top, int left, int bottom, int right){ 
     Insets insets = new Insets(top,left,bottom,right); 
     return insets; 
    } 

    //************************************************************************************** 
    // Interactive Object Methods 

    private JComboBox createStandardCombo(String[] defaultValues){ 
     JComboBox comboBox = new JComboBox(defaultValues); 
     ComboBoxRenderer cbr = new ComboBoxRenderer(); 
     DefaultListCellRenderer dlcr = new DefaultListCellRenderer(); 
     dlcr.setHorizontalTextPosition(SwingConstants.CENTER); 
     comboBox.setRenderer(cbr); 
     comboBox.setPrototypeDisplayValue("X" + guiCharSelDefault + "X"); 
     return comboBox; 
    } 

    //************************************************************************************** 
    // Object Action Methods 

    private void setComboBoxColorBackgroundWithMetalArrow(Color color){ 
     int componentCount = charCombo.getComponentCount(); 
     for (int i = 0; i < componentCount; i++) { 
      Component component = charCombo.getComponent(i); 
      if (component instanceof MetalComboBoxButton) { 
       MetalComboBoxButton metalComboBoxButton = 
         (MetalComboBoxButton) component; 
       Icon comboIcon = metalComboBoxButton.getComboIcon(); 
       BufferedImage bufferedImage = 
         new BufferedImage(
           comboIcon.getIconWidth(), 
           comboIcon.getIconHeight(), 
           BufferedImage.TYPE_INT_ARGB); 
       comboIcon.paintIcon(
         metalComboBoxButton, bufferedImage.getGraphics(), 0, 0); 
      } 
     } 
    } 

    private void setCharComboAction(){ 
     charCombo.addActionListener(
       new ActionListener() { 
        public void actionPerformed(ActionEvent e) { 
         String charName = ((JComboBox)(e.getSource())).getSelectedItem().toString(); 
         if (!(charName.equals(guiCharSelDefault[0]))){ 
          DefaultListCellRenderer dlcr = new DefaultListCellRenderer(); 
          DefaultComboBoxModel model = new DefaultComboBoxModel(characters); 
          model.setSelectedItem(charName); 
          charCombo.setModel(model); 
         } 
        } 
       } 
     ); 
    } 

    //************************************************************************************** 
    // Panel Methods 

    private JPanel createTopFrame(){ 
     JPanel pnl = new JPanel(); 

     pnl.setLayout(new GridBagLayout()); 

     setCharComboAction(); 
     pnl.add(charCombo, setGbc(0,0, 1,1, 0,0, "WEST", 0, 0, setInsets(0, 10, 0, 0))); 
     JButton button = new JButton("Button"); 
     pnl.add(button, setGbc(0,1, 1,1, 0,0, "WEST", 0, 0, setInsets(0, 10, 0, 0))); 

     pnl.setOpaque(false); 
     return pnl; 
    } 

    private JScrollPane createTopScrollPane(){ 
     JScrollPane scrollPane = new JScrollPane(); 
     Border raisedBevel = BorderFactory.createRaisedBevelBorder(); 
     Border lineBorder = BorderFactory.createMatteBorder(2, 2, 2, 2, new Color(224,224,224)); 
     Border loweredBevel = BorderFactory.createLoweredBevelBorder(); 
     Border compoundSetup = BorderFactory.createCompoundBorder(raisedBevel, lineBorder); 
     Border compoundFinal = BorderFactory.createCompoundBorder(compoundSetup, loweredBevel); 

     scrollPane.setBorder(compoundFinal); 
     scrollPane.setOpaque(false); 
     scrollPane.getViewport().setOpaque(false); 
     scrollPane.getViewport().setView(topFrame); 
     return scrollPane; 
    } 

    private JPanel createCenterFrame() { 
     JPanel pnl = new JPanel(); 
     Border raisedBevel = BorderFactory.createRaisedBevelBorder(); 
     Color lineColor = new Color(224, 224, 224); 
     Border lineBorder = BorderFactory.createMatteBorder(5, 5, 5, 5, lineColor); 
     Border loweredBevel = BorderFactory.createLoweredBevelBorder(); 
     Border compoundSetup = BorderFactory.createCompoundBorder(raisedBevel, lineBorder); 
     Border compoundFinal = BorderFactory.createCompoundBorder(compoundSetup, loweredBevel); 
     TitledBorder topFrameTitle = BorderFactory.createTitledBorder(compoundFinal, "Stuff"); 
     topFrameTitle.setTitleJustification(TitledBorder.CENTER); 

     pnl.setBorder(topFrameTitle); 
     pnl.setLayout(new GridBagLayout()); 

     pnl.setOpaque(false); 
     return pnl; 
    } 

    //************************************************************************************** 

    public static void main(String[] args) { 

     new TestGui(); 
    } 
} 

Étapes pour reproduire problème:

Cliquez sur le "caractère sélectionnez" combobox

enter image description here

Cliquez sur le "selectedTextOne" dans la liste. Note: "selectedTextThree" is only a different color because my mouse is hovered over it. This is behaving properly.

enter image description here

Cliquez sur le bouton. Note: the button doesn't actually do anything, we just do this so the combo box is no longer selected.

enter image description here

Remarquez comment les changements de zone de liste déroulante du vert au gris (nous voulons qu'il reste vert).

enter image description here

quelqu'un a une idée comment assurez-vous que la couleur d'arrière-plan (dans la zone de liste déroulante et non lui-même la liste) est définie pour la couleur de la valeur de texte?

Répondre

0

j'ai finalement trouvé la bonne combinaison. Voici le code ...

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

class ComboBoxRenderer extends JLabel implements ListCellRenderer 
{ 
    private Color selectionBackgroundColor; 
    private Color defaultBackgroundColor; 
    private DefaultListCellRenderer dlcr = new DefaultListCellRenderer(); 

    // Constructor 
    public ComboBoxRenderer() 
    { 
     setOpaque(true); 
     setHorizontalAlignment(CENTER); 
     setVerticalAlignment(CENTER); 
     defaultBackgroundColor = this.dlcr.getBackground(); // Have to set a color, else a compiler error will occur 
    } 

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) 
    { 
     // Set the list background color to default color (default color will show once selection is made) 
     selectionBackgroundColor = null; 
     Color mouseHoverHighlight = Color.LIGHT_GRAY; 
     setText((String)value); 
     // Check which item is selected 
     if(isSelected) 
     { 
      // Set background color of the item your cursor is hovering over to the original background color 
      String selectedText = getText(); 
      if (selectedText.equals("SelectedTextOne")){ 
       list.setSelectionBackground(Color.GREEN); 
      } else if (selectedText.equals("SelectedTextTwo")){ 
       list.setSelectionBackground(Color.RED); 
      } else { 
       list.setSelectionBackground(defaultBackgroundColor); 
      } 
      setBackground(mouseHoverHighlight); 
     } 
     else 
     { 
      // Set background to specific color depending on text value 
      String selectedTextInDropdownList = getText(); 
      if (selectedTextInDropdownList.equals("SelectedTextOne")) { 
       selectionBackgroundColor = Color.GREEN; 
      } else if (selectedTextInDropdownList.equals("SelectedTextTwo")) { 
       selectionBackgroundColor = Color.RED; 
      } else { 
       selectionBackgroundColor = defaultBackgroundColor; 
      } 
     } 


     return this; 
    } 

    @Override 
    public boolean isOpaque() { 
     return true; 
    } 

    @Override 
    public void setBackground(Color bg) { 
     super.setBackground(bg); //To change body of generated methods, choose Tools | Templates. 
    } 

    @Override 
    public Color getBackground() { 
     return selectionBackgroundColor == null ? super.getBackground() : selectionBackgroundColor; 
    } 
} 
2

Ainsi, après beaucoup de jouer autour, ce ...

class ComboBoxRenderer extends JLabel implements ListCellRenderer { 

    // Constructor 
    public ComboBoxRenderer() { 
     setOpaque(true); 
     setHorizontalAlignment(CENTER); 
     setVerticalAlignment(CENTER); 
    } 

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 
     Color mouseHoverHighlight = Color.LIGHT_GRAY; 
     setBackground(list.getBackground()); 
     setText((String) value); 

     // Check which item is selected 
     if (isSelected) { 
      // Set background color of the item your cursor is hovering over to the original background color 
      setBackground(mouseHoverHighlight); 
     } else { 
      // Set background to specific color depending on text value 
      String selectedText = getText(); 
      if (selectedText.equals("SelectedTextOne")) { 
       setBackground(Color.GREEN); 
      } else if (selectedText.equals("SelectedTextTwo")) { 
       setBackground(Color.RED); 
      } 
     } 

     // Do nothing about the text and font to be displayed 
     setFont(list.getFont()); 

     return this; 
    } 
} 

semble fonctionner.Il semble que le réglage du texte après que la couleur de fond ait causé des problèmes, déclenchant probablement une repeinte ou quelque chose.

Voilà pourquoi je vous recommande d'utiliser un DefaultListCellRenderer à la place, il est basé sur un JLabel et a été optimisé pour réduire ce genre de mises à jour

+0

Jusqu'à présent, le seul problème est qu'après la sélection, la zone de liste déroulante est toujours surlignée en gris clair (jusqu'à ce que vous sélectionniez autre chose). Une idée de comment résoudre ce problème? –

+0

Lors de mes tests, il a été remplacé par l'aspect et la convivialité (MacOS). J'ai également noté que 'cellHasFocus' est' false' quand vous essayez de choisir la valeur de la liste, mais 'true' quand c'est l'élément" choisi ", donc peut-être jouer avec cela – MadProgrammer

+0

J'ai mis à jour la question et le code ainsi vous pourriez voir le problème que j'ai toujours. –