简体   繁体   中英

Rounded Corner for JComboBox

I want make JComboBox has rounded corners. And i came with this code :

public class BPosCmbBox extends JCboEdc {

    public BPosCmbBox() {
       super();
       setBorder(new RoundBorder());
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
        super.paint(g); //To change body of generated methods, choose Tools | Templates.
    }

}



public class RoundBorder extends AbstractBorder {

    Color bgColor = new Color(0, 0, 0, 220);

    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        ((Graphics2D) g).setColor(bgColor);
        ((Graphics2D) g).drawRoundRect(x, y, width - 1, height - 1, 12, 12);
    }

    public Insets getBorderInsets(Component c) {
        return new Insets(3, 6, 3, 3);
    }

    public Insets getBorderInsets(Component c, Insets insets) {
        insets.top = insets.left = insets.bottom = insets.right = 3;
        return insets;
    }
}

But it still has square box inside like this

在此处输入图片说明

Is there any way to remove square box inside? And is this possible to has drop down list with rounded corners too?

在此处输入图片说明

Here's my version, using BasicComboBoxUI instead of MetalComboBoxUI :

截图

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

public class RoundedCornerComboBoxTest {
  private static final Color BACKGROUND = Color.BLACK;
  private static final Color FOREGROUND = Color.WHITE;
  private static final Color SELECTIONFOREGROUND = Color.ORANGE;
  private JComponent makeUI() {
    UIManager.put("ComboBox.foreground", FOREGROUND);
    UIManager.put("ComboBox.background", BACKGROUND);
    UIManager.put("ComboBox.selectionForeground", SELECTIONFOREGROUND);
    UIManager.put("ComboBox.selectionBackground", BACKGROUND);

    UIManager.put("ComboBox.buttonDarkShadow", BACKGROUND);
    UIManager.put("ComboBox.buttonBackground", FOREGROUND);
    UIManager.put("ComboBox.buttonHighlight",  FOREGROUND);
    UIManager.put("ComboBox.buttonShadow",     FOREGROUND);

    UIManager.put("ComboBox.border", new RoundedCornerBorder());
    JComboBox<String> combo1 = new JComboBox<>(makeModel());
    combo1.setUI(new BasicComboBoxUI());
    Object o = combo1.getAccessibleContext().getAccessibleChild(0);
    if (o instanceof JComponent) {
      JComponent c = (JComponent) o;
      c.setBorder(new RoundedCornerBorder());
      c.setForeground(FOREGROUND);
      c.setBackground(BACKGROUND);
    }
    combo1.addPopupMenuListener(new HeavyWeightContainerListener());

    UIManager.put("ComboBox.border", new RoundedCornerBorder1());
    JComboBox<String> combo2 = new JComboBox<>(makeModel());
    combo2.setUI(new BasicComboBoxUI());
    o = combo2.getAccessibleContext().getAccessibleChild(0);
    if (o instanceof JComponent) {
      JComponent c = (JComponent) o;
      c.setBorder(new RoundedCornerBorder2());
      c.setForeground(FOREGROUND);
      c.setBackground(BACKGROUND);
    }
    combo2.addPopupMenuListener(new HeavyWeightContainerListener());

    JPanel p = new JPanel();
    p.add(combo1);
    p.add(combo2);
    p.setOpaque(true);
    p.setBackground(Color.GRAY);
    return p;
  }
  private static DefaultComboBoxModel<String> makeModel() {
    DefaultComboBoxModel<String> m = new DefaultComboBoxModel<>();
    m.addElement("1234");
    m.addElement("5555555555555555555555");
    m.addElement("6789000000000");
    return m;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new RoundedCornerComboBoxTest().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

class HeavyWeightContainerListener implements PopupMenuListener {
  @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        JComboBox combo = (JComboBox) e.getSource();
        Accessible a = combo.getUI().getAccessibleChild(combo, 0);
        if (a instanceof BasicComboPopup) {
          BasicComboPopup pop = (BasicComboPopup) a;
          Container top = pop.getTopLevelAncestor();
          if (top instanceof JWindow) {
            //http://ateraimemo.com/Swing/DropShadowPopup.html
            System.out.println("HeavyWeightContainer");
            ((JWindow) top).setBackground(new Color(0x0, true));
          }
        }
      }
    });
  }
  @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
  @Override public void popupMenuCanceled(PopupMenuEvent e) {}
}

class RoundedCornerBorder extends AbstractBorder {
  protected static final int ARC = 12;
  @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 = ARC;
    int w = width  - 1;
    int h = height - 1;

    Area round = new Area(new RoundRectangle2D.Float(x, y, w, h, r, r));
    if (c instanceof JPopupMenu) {
      g2.setPaint(c.getBackground());
      g2.fill(round);
    } else {
      Container parent = c.getParent();
      if (Objects.nonNull(parent)) {
        g2.setPaint(parent.getBackground());
        Area corner = new Area(new Rectangle2D.Float(x, y, width, height));
        corner.subtract(round);
        g2.fill(corner);
      }
    }
    g2.setPaint(c.getForeground());
    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.set(4, 8, 4, 8);
    return insets;
  }
}

class RoundedCornerBorder1 extends RoundedCornerBorder {
  //http://ateraimemo.com/Swing/RoundedComboBox.html
  @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 = ARC;
    int w = width  - 1;
    int h = height - 1;

    Area round = new Area(new RoundRectangle2D.Float(x, y, w, h, 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 (Objects.nonNull(parent)) {
      g2.setPaint(parent.getBackground());
      Area corner = new Area(new Rectangle2D.Float(x, y, width, height));
      corner.subtract(round);
      g2.fill(corner);
    }

    g2.setPaint(c.getForeground());
    g2.draw(round);
    g2.dispose();
  }
}

class RoundedCornerBorder2 extends RoundedCornerBorder {
  @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 = ARC;
    int w = width  - 1;
    int h = height - 1;

    Path2D.Float p = new Path2D.Float();
    p.moveTo(x, y);
    p.lineTo(x, y + h - r);
    p.quadTo(x, y + h, x + r, y + h);
    p.lineTo(x + w - r, y + h);
    p.quadTo(x + w, y + h, x + w, y + h - r);
    p.lineTo(x + w, y);
    p.closePath();
    Area round = new Area(p);

    g2.setPaint(c.getBackground());
    g2.fill(round);

    g2.setPaint(c.getForeground());
    g2.draw(round);
    g2.setPaint(c.getBackground());
    g2.drawLine(x + 1, y, x + width - 2, y);
    g2.dispose();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM