Customizing JTextField
Asked Answered
C

3

6

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.

Chromosphere answered 15/5, 2011 at 11:21 Comment(7)
@user616693: Do you want to customize a single, concrete JTextFile, or you're trying to make all your components look better? In this case, try using other Look&Feels, such as Nimbus, SeaGlass or Substance.Ermentrude
I want to customize a single concrete jtextfields size and add a rounded border without the view or document is visible, and neither nimbus, Seaglass or substance provide me with a rounded rectangular jtextfield atleast not from what I can read in the sourceChromosphere
Have you tried implementing your own Border and set it to JTextField? That would be the simplest solution if it works.Subsidy
Indeed I have, but that ends up with the "ugly" document/view background (in my case white as normal/regular texfields) is equipped with and setting the opaque to false will render the textfield but without the background, I'm looking for the function or method that will let me clip the view or the background to be rounded and return as normalChromosphere
In a side comment I must say that you users are really fast to respond. ThanksChromosphere
Well I got the answer my self :O, I hacked it with a JPanel with a painted background and made the textfield opaque(false) and added the border to the jtextfield JTextField textfield2 = new JTextField(25); textfield2.setOpaque(false); textfield2.setBorder(new BlueBorder()); myPanel.add(textfield2); // myPanel is a subclassed JPanel with custom rendering/painting I really hoped for a better or a more pluggable look-and-feel style solution, but this will do for a while. Thanks all for reading this question and have a nice day.Chromosphere
Take a look at: Change JButton Shape while respecting Look And FeelPedro
F
5

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

Franfranc answered 29/5, 2014 at 2:14 Comment(0)
H
1

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

Hobson answered 15/5, 2011 at 17:51 Comment(1)
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.Chromosphere
J
0

If you want to customizing single components, there's a way to do that, in any component actually. Please check this tutorial : http://www.eecchhoo.wordpress.com/2012/11/05/screencast-swingmakeover-extreme-java-gui-programming

It contains a short brief and a link to download the video tutorial. FYI, the videos are in indonesian language, so if you have problem to follow the step, there's also another link to download the project that he used to create the tutorial.

Please tell me if you have any problem. I hope that link will help

Jordaens answered 31/5, 2012 at 10:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.