2017-04-26 119 views
0

更新问题定制JComboBoxRenderer更改背景颜色取决于文本选择

第1部分:本来,我是第一次去删除突出显示选择的项目已被选择后(因为这是搞乱背景颜色进行选择)。只见这可能从这里完成>Delete highlighting in JComboBox - (解决)

第2部分:现在...我试图把它识别所选文本,改变背景颜色(选中时,而不是当鼠标悬停在列表中的项目上时),具体取决于选择哪个文本。 (解决 - - 见我的解决方案)中选择另一个对象时(去选择组合框),背景颜色变回默认它确实改变了颜色的文本匹配,但是

3部分:另外,我希望为下拉列表中的文本显示背景颜色(而鼠标不在其上方悬停)。 - (解决)

这里是代码...

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

编辑:也...这里是鼓起来的GUI所以你可以看到它是如何表现的代码。 ..

EDIT2:编辑代码而不在图像中示出的背景编译

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

步骤来重现问题:

单击 “选择角色” 下拉框

enter image description here

在列表中点击 “selectedTextOne” 项目。 Note: "selectedTextThree" is only a different color because my mouse is hovered over it. This is behaving properly.

enter image description here

点击按钮。 Note: the button doesn't actually do anything, we just do this so the combo box is no longer selected.

enter image description here

通知从绿色组合框的变化如何为灰色(我们希望它留青)。

enter image description here

任何人有任何想法如何确保背景色(在组合框中本身,而不是列表)设置文本值的颜色?

回答

0

的我终于找到了正确的组合。这里是代码...

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

于是,经过太多的出场左右,这...

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

似乎工作。似乎在背景颜色导致问题后设置文本,可能会触发重绘或其他事情。

这就是为什么我会建议使用DefaultListCellRenderer相反,它是基于一个JLabel并进行了优化,以减少这些类型的更新

+0

到目前为止,唯一的问题是现在是选择后,组合框仍然用浅灰色突出显示(直到你选择其他东西)。任何想法如何解决这个问题? –

+0

在我的测试中,它被外观和感觉(MacOS)所覆盖。我也注意到'cellHasFocus'在你尝试从列表中选择'false'的时候是'false',但是当它是'selected'项时是'true',所以我可能会玩这个 – MadProgrammer

+0

我更新了问题和代码你可以看到我仍然存在的问题。 –