如何制作圆角矩形JTextField?

我想制作一个圆形矩形JTextField。 我写了一个AbstractBorder子类来实现它。但是我遇到了一些问题。 我的要求是: 在此处输入图像描述

我得到的是:

在此处输入图像描述

我的代码是:

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.Graphics; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.AbstractBorder; import javax.swing.border.EmptyBorder; public class JTextFieldTest { JTextField textField; boolean activate = false; public void createUI(){ JFrame frame = new JFrame("Test JTextField"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(true); MainPanel mainPanel = new MainPanel(); frame.add(mainPanel,BorderLayout.CENTER); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { JTextFieldTest jTextFieldTest = new JTextFieldTest(); jTextFieldTest.createUI(); } @SuppressWarnings("serial") class MainPanel extends JPanel{ public MainPanel(){ textField = new JTextField("Please input:"); Font fieldFont = new Font("Arial", Font.PLAIN, 20); textField.setFont(fieldFont); textField.setBackground(Color.white); textField.setForeground(Color.gray.brighter()); textField.setColumns(30); textField.setBorder(BorderFactory.createCompoundBorder(new CustomeBorder(), new EmptyBorder(new Insets(10, 20, 10, 20)))); textField.addActionListener(new FieldListener()); textField.addMouseListener(new FieldMouseListener()); add(textField,BorderLayout.CENTER); setBackground(Color.blue); setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); } } @SuppressWarnings("serial") class CustomeBorder extends AbstractBorder{ @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { // TODO Auto-generated method stub super.paintBorder(c, g, x, y, width, height); g.setColor(Color.black); g.drawRoundRect(x, y, width, height, 20, 20); } } class FieldListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub System.out.println(textField.getText()); } } class FieldMouseListener implements MouseListener{ @Override public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub if(activate == false){ textField.setText(""); } activate = true; textField.setForeground(Color.black); } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } } } 

我可以通过使用获得另一种效果

textField.setOpaque(假);

g.setColor(Color.white); g.drawRoundRect(x,y,width – 1,height – 1,20,20);

另一个影响是: 在此处输入图像描述

总而言之,我能做些什么来实现我的要求?

@Arijit,这是你的解决方案在我的计算机上运行时的效果。 在此处输入图像描述在此处输入图像描述

使用TextBubbleBorder

在此处输入图像描述

 import java.awt.*; import java.awt.geom.*; import javax.swing.*; import javax.swing.border.AbstractBorder; class TextBubbleBorder extends AbstractBorder { private Color color; private int thickness = 4; private int radii = 8; private int pointerSize = 7; private Insets insets = null; private BasicStroke stroke = null; private int strokePad; private int pointerPad = 4; RenderingHints hints; TextBubbleBorder( Color color) { this(color, 4, 8, 7); } TextBubbleBorder( Color color, int thickness, int radii, int pointerSize) { this.thickness = thickness; this.radii = radii; this.pointerSize = pointerSize; this.color = color; stroke = new BasicStroke(thickness); strokePad = thickness/2; hints = new RenderingHints( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int pad = radii + strokePad; int bottomPad = pad + pointerSize + strokePad; insets = new Insets(pad,pad,bottomPad,pad); } @Override public Insets getBorderInsets(Component c) { return insets; } @Override public Insets getBorderInsets(Component c, Insets insets) { return getBorderInsets(c); } @Override public void paintBorder( Component c, Graphics g, int x, int y, int width, int height) { Graphics2D g2 = (Graphics2D)g; int bottomLineY = height-thickness-pointerSize; RoundRectangle2D.Double bubble = new RoundRectangle2D.Double( 0+strokePad, 0+strokePad, width-thickness, bottomLineY, radii, radii ); Polygon pointer = new Polygon(); // left point pointer.addPoint( strokePad+radii+pointerPad, bottomLineY); // right point pointer.addPoint( strokePad+radii+pointerPad+pointerSize, bottomLineY); // bottom point pointer.addPoint( strokePad+radii+pointerPad+(pointerSize/2), height-strokePad); Area area = new Area(bubble); area.add(new Area(pointer)); g2.setRenderingHints(hints); Area spareSpace = new Area(new Rectangle(0,0,width,height)); spareSpace.subtract(area); g2.setClip(spareSpace); g2.clearRect(0,0,width,height); g2.setClip(null); g2.setColor(color); g2.setStroke(stroke); g2.draw(area); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JTextField o = new JTextField( "The quick brown fox jumps over the lazy dog!"); o.setBorder(new TextBubbleBorder(Color.MAGENTA.darker(),2,4,0)); JOptionPane.showMessageDialog(null, o); } }); } } 

我有一个解决方案,我不需要使用

textField.setOpaque(假);

我只是使用以下代码填充空间。

 @SuppressWarnings("serial") class CustomeBorder extends AbstractBorder{ @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { // TODO Auto-generated method stubs super.paintBorder(c, g, x, y, width, height); Graphics2D g2d = (Graphics2D)g; g2d.setStroke(new BasicStroke(10)); g2d.setColor(new Color(68,184,224)); g2d.drawRoundRect(x, y, width - 1, height - 1, 20, 20); } } 

您应该根据JTextField调整BasicStroke的宽度。 最终结果是: 在此处输入图像描述

在此处输入图像描述

用这个:

 JTextField Mytxtfield = new JTextField() {protected void paintComponent( Graphics g ) { if ( !isOpaque( ) ) { super.paintComponent( g ); return; } Graphics2D g2d = (Graphics2D)g; GradientPaint gp = new GradientPaint( 0, 0, color1, 0, 20, color2); g2d.setPaint( gp ); // g2d.fillRect( 0, 0, w, h ); g2d.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 10, 10); setOpaque( false ); super.paintComponent( g ); setOpaque( true ); }}; 

完整的工作代码:

 import java.awt.Color; import java.awt.EventQueue; import java.awt.Font; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Shape; import java.awt.SystemColor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.border.EmptyBorder; import javax.xml.parsers.ParserConfigurationException; import org.xml.sax.SAXException; public class DBconnection extends JFrame { private JPanel contentPane; private JTextField textFieldHost; private Color color2 = Color.white; private Color color1 = Color.white; public DBconnection() throws SAXException, IOException, ParserConfigurationException { setTitle("Connect To MDM Database"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(450, 200, 410, 280); contentPane = new JPanel(); contentPane.setBackground(SystemColor.inactiveCaption); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); GridBagLayout gbl_contentPane = new GridBagLayout(); gbl_contentPane.columnWidths = new int[]{0, 0, 0, 0}; gbl_contentPane.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; gbl_contentPane.columnWeights = new double[]{0.0, 0.0, 1.0, Double.MIN_VALUE}; gbl_contentPane.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE}; contentPane.setLayout(gbl_contentPane); textFieldHost = new JTextField() {protected void paintComponent( Graphics g ) { if ( !isOpaque( ) ) { super.paintComponent( g ); return; } Graphics2D g2d = (Graphics2D)g; GradientPaint gp = new GradientPaint( 0, 0, color1, 0, 20, color2); g2d.setPaint( gp ); // g2d.fillRect( 0, 0, w, h ); g2d.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 10, 10); setOpaque( false ); super.paintComponent( g ); setOpaque( true ); }}; GridBagConstraints gbc_textFieldHost = new GridBagConstraints(); gbc_textFieldHost.insets = new Insets(20, 40, 5, 0); gbc_textFieldHost.fill = GridBagConstraints.HORIZONTAL; gbc_textFieldHost.gridwidth=3; gbc_textFieldHost.gridx = 2; gbc_textFieldHost.gridy = 4; gbc_textFieldHost.ipady=5; contentPane.add(textFieldHost, gbc_textFieldHost); textFieldHost.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 2,2,2)); } /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { DBconnection frame = new DBconnection(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } } 

另外,通过更改color1和color2的值,您可以获得渐变效果。

我修改了你的代码并得到了这个: 在此处输入图像描述

码:

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.AbstractBorder; public class JTextFieldTest { JTextField textField; boolean activate = false; public void createUI(){ JFrame frame = new JFrame("Test JTextField"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(true); MainPanel mainPanel = new MainPanel(); frame.add(mainPanel,BorderLayout.CENTER); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { JTextFieldTest jTextFieldTest = new JTextFieldTest(); jTextFieldTest.createUI(); } @SuppressWarnings("serial") class MainPanel extends JPanel{ public MainPanel(){ textField = new JTextField("Test JTextField") {protected void paintComponent( Graphics g ) { if ( !isOpaque( ) ) { super.paintComponent( g ); return; } Graphics2D g2d = (Graphics2D)g; GradientPaint gp = new GradientPaint( 0, 0, Color.white, 0, 20, Color.white); g2d.setPaint( gp ); // g2d.fillRect( 0, 0, w, h ); g2d.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 20, 20); setOpaque( false ); super.paintComponent( g ); setOpaque( true ); }}; textField.setBorder(BorderFactory.createEmptyBorder()); Font fieldFont = new Font("Arial", Font.PLAIN, 20); textField.setFont(fieldFont); textField.setColumns(30); textField.addActionListener(new FieldListener()); textField.addMouseListener(new FieldMouseListener()); add(textField,BorderLayout.CENTER); setBackground(Color.blue); setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); } } class FieldListener implements ActionListener{ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub System.out.println(textField.getText()); } } class FieldMouseListener implements MouseListener{ public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub if(activate == false){ textField.setText(""); } activate = true; textField.setForeground(Color.black); } public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } } }