Customizing JTextField

10,053

Solution 1

I wanted to solve almost same problem yesterday and I got some inspiration by your thought and I finally find the solution.

  1. To make document inside the border of JTextField, you can use

javax.swing.border.EmptyBorder.EmptyBorder(Insets borderInsets)

2.To avoid the white space in four corners of JTextField, you can use

g2d.setStroke(new BasicStroke(12));

before drawing the round rectangle.The width of stroke is based on your demand and just make it wide enough to cover the space in corner.

It's the code:

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
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();
        mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
        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();
    }

    public void setActivate(boolean activate){
        this.activate = activate;
    }

    @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(15, 25, 15, 25))));
            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 stubs
            super.paintBorder(c, g, x, y, width, height);
            Graphics2D g2d = (Graphics2D)g;
            g2d.setStroke(new BasicStroke(12));
            g2d.setColor(Color.blue);
            g2d.drawRoundRect(x, y, width - 1, height - 1, 25, 25);
        }   
    }

    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

        }
    }
}

It's the effect:

enter image description here

For more details , you can browse How to make a round rectangle JTextField

Solution 2

You should be able to do this with Swing borders. I published some code for how to do rounded borders long ago, here - perhaps you can adapt it: http://weblogs.java.net/blog/timboudreau/archive/2005/02/jnn_just_got_pr.html

Share:
10,053
OMG-1
Author by

OMG-1

BY DAY: Develop Facebook Market automations for a Swedish startup company. BY NIGHT: Reading and solve challenges on codewars. Learning more on SQL, Javascript and Python. Developing applications and websites for the last 5 years, programming since 1998. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus vel ornare mi. Donec sit amet quam lacinia, rutrum purus bibendum, accumsan elit. Pellentesque in augue nec augue lacinia porttitor vel sit amet mi. Morbi et odio efficitur, ornare magna ac, egestas sapien. Donec maximus eleifend nulla imperdiet maximus. Proin erat odio, pulvinar in rutrum sed, viverra et magna. Integer pulvinar hendrerit libero vel eleifend. Maecenas volutpat aliquam est. Suspendisse potenti. Ut venenatis ante tellus, quis imperdiet ex tincidunt non. Nunc dignissim sapien nisl, ut iaculis ipsum dapibus condimentum. Praesent mauris ante, tincidunt sed hendrerit a, interdum eget purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nullam congue condimentum nulla, vestibulum fringilla nunc sollicitudin sed. Mauris tellus est, facilisis eu eros eget, condimentum consequat est. Proin ut auctor erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla hendrerit, quam quis venenatis egestas, quam dolor luctus quam, a luctus lorem purus quis orci. Praesent sed massa ut nisl finibus viverra sit amet ut purus. Praesent vitae mauris id lectus malesuada scelerisque in vel ligula. Aenean tellus dolor, scelerisque et dapibus vel, facilisis in leo. Sed rutrum sem arcu, et fringilla erat vestibulum non. Quisque molestie pellentesque mauris, et aliquam tortor tristique vel. Donec enim augue, pretium pellentesque finibus quis, condimentum nec risus. Vivamus eleifend accumsan mi, non suscipit eros finibus et. Donec lacinia sed dui eu fermentum. Morbi ultrices tristique sem, quis aliquam risus scelerisque ac. Ut auctor suscipit mi vel consectetur. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec eget velit nec nibh tempor congue sed non quam. Pellentesque vitae eros quis erat iaculis egestas. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed non dapibus turpis. Duis lacinia erat ut diam ornare, eget convallis turpis sollicitudin. Nam vel elit facilisis, luctus nisi ut, posuere nunc. Sed ut turpis quis enim tincidunt laoreet. Nam sit amet urna risus. Donec sed varius diam. Sed dolor dui, suscipit vitae purus id, varius tempus dui. Duis sit amet felis ante. Vivamus laoreet ante enim, ut imperdiet arcu consequat sagittis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Curabitur pretium accumsan augue a tempus. Nunc sed ornare orci.

Updated on October 02, 2022

Comments

  • OMG-1
    OMG-1 over 1 year

    I would like to know how to customize the ui of a jtextfield so I could create rounded rectangular border without the document going outside the border.

    So far I think I have tried the most of what I can think of, I have created a new FieldView class and changed the shape in the paint method according to my customized border that draw rounded rects, the only way I sort of managed to get rid of the white textfield document/view was to set it opaque but I think there should be another way without setting the opaque value.

    Have You any experience in customizing the laf of a jtextfield please write back, I have even read the Core Swing advanced book without luck and if you try searching with google please let me know the search phrase as I have tried with keywords like "styling","customizing","ui","plaf","laf" and what not.

    I sincerely hope you can give me a nudge in the right direction and I hope nobody will make a flamewar out of this, I have truly used all my resources I can think of.

    Sincerely regards.

  • OMG-1
    OMG-1 almost 13 years
    Thank you Tim Boudreau for your answer, it is very interesting your code and I will look into it. I found another way but its an ugly hack, I made my textfield transparent, customized a JPanel paint method and added both to a frame, but I think your method is alot more future and object oriented way to go.