2017-04-26 123 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

我更新了問題和代碼你可以看到我仍然存在的問題。 –