2

I have this following combo box, where i am able to create my combo box with items etc, but the look is not same as JTextField. How can i make JCombobox look same like JTextField?

enter image description here

MyComboBox.java:

import java.awt.Color;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.plaf.basic.BasicComboBoxUI;

public class MyComboBox extends JComboBox {
  public MyComboBox(String[] name) {
    Border border = BorderFactory.createEmptyBorder(11, 11, 11, 11);
    JComboBox cb = new JComboBox(name);
    cb.setUI(new BasicComboBoxUI() {
        @Override
        protected JButton createArrowButton() {
            return new JButton() {
                    @Override
                    public int getWidth() {
                            return 0;
                    }
            };
        }
    });

    setModel(cb.getModel());    
    setOpaque(false);
    setBorder(new LineBorder(Color.black, 1, true));
    //setBackground(Color.white);
    setVisible(true); 


  }
//  public void paintComponent(Graphics g) {
//      super.paintComponent(g);                
//      g.setColor(new Color(red, green, blue) );
//      g.fillOval(125, 125, 50, 50);
//  }  
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319

3 Answers3

3
  • best of all could be use Look and Feels

  • JComboBox has two states, JComboBox can be Editable and Non_Editable (default)

  • without CustomUI (as example by @aterai), but Look and Feel sensitive, only for Metal Look and Feel

enter image description here

import java.awt.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.metal.MetalComboBoxButton;

public class MyComboBox {

    private Vector<String> listSomeString = new Vector<String>();
    private JComboBox someComboBox = new JComboBox(listSomeString);
    private JComboBox editableComboBox = new JComboBox(listSomeString);
    private JComboBox non_EditableComboBox = new JComboBox(listSomeString);
    private JFrame frame;

    public MyComboBox() {
        listSomeString.add("-");
        listSomeString.add("Snowboarding");
        listSomeString.add("Rowing");
        listSomeString.add("Knitting");
        listSomeString.add("Speed reading");
//
        someComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        someComboBox.setFont(new Font("Serif", Font.BOLD, 16));
        someComboBox.setEditable(true);
        someComboBox.getEditor().getEditorComponent().setBackground(Color.YELLOW);
        ((JTextField) someComboBox.getEditor().getEditorComponent()).setBackground(Color.YELLOW);
//        
        editableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        editableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
        editableComboBox.setEditable(true);
        JTextField text = ((JTextField) editableComboBox.getEditor().getEditorComponent());
        text.setBackground(Color.YELLOW);
        JComboBox coloredArrowsCombo = editableComboBox;
        Component[] comp = coloredArrowsCombo.getComponents();
        for (int i = 0; i < comp.length; i++) {
            if (comp[i] instanceof MetalComboBoxButton) {
                MetalComboBoxButton coloredArrowsButton = (MetalComboBoxButton) comp[i];
                coloredArrowsButton.setBackground(null);
                break;
            }
        }
//        
        non_EditableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        non_EditableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
//
        frame = new JFrame();
        frame.setLayout(new GridLayout(0, 1, 10, 10));
        frame.add(someComboBox);
        frame.add(editableComboBox);
        frame.add(non_EditableComboBox);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(100, 100);
        frame.pack();
        frame.setVisible(true);
    }

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

            @Override
            public void run() {
                MyComboBox aCTF = new MyComboBox();
            }
        });
    }
}
Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • @aterai please is there another way how to get/put BasicButtonUI from JComboBox (another as in your nice example) – mKorbel Apr 16 '12 at 08:04
  • You bet! "JComboBox does not behave same as JTextField" sounds like "looking for editable JComboBox". – aterai Apr 16 '12 at 08:34
  • @aterai not, wrong, I'm not, why???, because really no idea how to solve, crazy AbstractButton, eeerrgggt – mKorbel Apr 16 '12 at 08:37
2

I guess you are meaning RoundedCornerBorder:

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.basic.*;

public class RoundedComboBoxTest {
  public JComponent makeUI() {
    UIManager.put("Panel.background", Color.GRAY);
    UIManager.put("ComboBox.foreground", Color.BLACK);
    UIManager.put("ComboBox.background", Color.GRAY);
    UIManager.put("ComboBox.selectionForeground", Color.WHITE);
    UIManager.put("ComboBox.selectionBackground", Color.GRAY);
    UIManager.put("ComboBox.buttonDarkShadow", Color.BLACK);
    UIManager.put("ComboBox.border", new RoundedCornerBorder());

    DefaultComboBoxModel<String> m = new DefaultComboBoxModel<>();
    m.addElement("1234");
    m.addElement("5555555555555555555555");
    m.addElement("6789000000000");
    JComboBox<String> combo = new JComboBox<>(m);
    combo.setUI(new BasicComboBoxUI() {
      @Override protected JButton createArrowButton() {
        JButton b = super.createArrowButton();
        b.setContentAreaFilled(false);
        b.setBackground(Color.GRAY);
        b.setBorder(BorderFactory.createEmptyBorder());
        return b;
      }
    });
    Object o = combo.getAccessibleContext().getAccessibleChild(0);
    ((JComponent)o).setBorder(
        BorderFactory.createMatteBorder(0,1,1,1,Color.BLACK));
    JPanel p = new JPanel(new BorderLayout());
    p.add(combo, BorderLayout.NORTH);
    p.setOpaque(true);
    p.setBackground(Color.GRAY);
    p.setBorder(BorderFactory.createEmptyBorder(15,15,15,15));
    return p;
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new RoundedComboBoxTest().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}
class RoundedCornerBorder extends AbstractBorder {
  @Override public void paintBorder(
      Component c, Graphics g, int x, int y, int width, int height) {
    Graphics2D g2 = (Graphics2D)g.create();
    g2.setRenderingHint(
        RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    int r = 12;
    Area round = new Area(
        new RoundRectangle2D.Float(x, y, width-1, height-1, r, r));
    Rectangle b = round.getBounds();
    b.setBounds(b.x, b.y + r, b.width, b.height - r);
    round.add(new Area(b));

    Container parent = c.getParent();
    if(parent!=null) {
      g2.setColor(parent.getBackground());
      Area corner = new Area(new Rectangle2D.Float(x, y, width, height));
      corner.subtract(round);
      g2.fill(corner);
    }
    g2.setColor(Color.BLACK);
    g2.draw(round);
    g2.dispose();
  }
  @Override public Insets getBorderInsets(Component c) {
    return new Insets(4, 8, 4, 8);
  }
  @Override public Insets getBorderInsets(Component c, Insets insets) {
    insets.left = insets.right = 8;
    insets.top = insets.bottom = 4;
    return insets;
  }
}
aterai
  • 9,658
  • 4
  • 35
  • 44
1

You will have to define your own custom renderer, check out this tutorial as how to define one.

You can also set your background and foreground in your MyComboBox.java but that will not have an impact on selected item foreground, background.

mprabhat
  • 20,107
  • 7
  • 46
  • 63