Прозрачное JTexfield с фоновым изображением

#java #swing #jtextfield

#java #качать #jtextfield

Вопрос:

Я хотел знать, как установить для изображения значение a, JTextField если оно прозрачное, или как сделать так, чтобы мое JTextField выглядело следующим образом:

Фоновое изображение JTextField

Вот как я делаю свое поле прозрачным, но я не могу установить его фоновое изображение:

 //Step 1: Remove the border line to make it look like a flat surface.  
field.setBorder(BorderFactory.createLineBorder(Color.white, 0));  

//Step 2: Set the background color to null to remove the background.  
field.setBackground(null);  
  

Ответ №1:

Все компоненты Swing имеют концепцию прозрачности, которая контролируется с помощью opaque свойства. Установка фона на null палатки, чтобы сохранить цвет фона поля по умолчанию в пользовательском интерфейсе.

Сказав это, некоторые компоненты могут игнорировать это (частично или полностью). В этом случае мы можем обмануть…

В следующем примере установите поле прозрачным с помощью opaque свойства, это важно, так как RepaintManager не будет закрашивать области за компонентами, если они не прозрачны, и использовать полностью прозрачный цвет фона.

Поле

 import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestTextField {

    public static void main(String[] args) {
        new TestTextField();
    }

    public TestTextField() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JTextField field = new JTextField(20);
                field.setBackground(new Color(0, 0, 0, 0));
                field.setOpaque(false);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.getContentPane().setBackground(Color.RED);
                frame.setLayout(new GridBagLayout());
                frame.add(field);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}
  

Обновлено на основе комментариев…

Это очень конкретный пример, разработанный для предоставления прямого ответа на представленную проблему. По сути, это создает пользовательскую границу и использует Image для отображения «границы»

Пример границы

 import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;

public class TestTextField {

    public static void main(String[] args) {
        new TestTextField();
    }

    public TestTextField() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JTextField field = new JTextField(20);
                try {
                    BufferedImage img = ImageIO.read(getClass().getResource("/FieldBorder.png"));
                    field.setBorder(new ImageBorder(img, 8, 6));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(field);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ImageBorder implements Border {

        private BufferedImage img;
        private int bottomMargin;
        private int leftMargin;

        public ImageBorder(BufferedImage img, int leftMargin, int bottomMargin) {
            this.img = img;
            this.bottomMargin = bottomMargin;
            this.leftMargin = leftMargin;
        }

        @Override
        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
            g.drawImage(img, x, y   height - img.getHeight(), c);
        }

        @Override
        public Insets getBorderInsets(Component c) {
            return new Insets(0, leftMargin, bottomMargin, 0);
        }

        @Override
        public boolean isBorderOpaque() {
            return false;
        }

    }

}
  

Теперь это также можно было бы сделать с помощью пользовательского рисования внутри пользовательского Border вместо этого, но так было быстрее 😉

Другой вариант…

Заключается в том, чтобы просто использовать JPanel и добавить поле и JLabel , например, удерживая контур границы вместе…

Составное поле

 import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;

public class TestTextField {

    public static void main(String[] args) {
        new TestTextField();
    }

    public TestTextField() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JTextField field = new JTextField(20);
                field.setBorder(null);

                JPanel fieldPane = new JPanel(new GridBagLayout());
                fieldPane.setBackground(Color.WHITE);
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                gbc.anchor = GridBagConstraints.WEST;
                gbc.insets = new Insets(0, 8, 0, 0);
                fieldPane.add(field, gbc);

                try {
                    BufferedImage img = ImageIO.read(getClass().getResource("/FieldBorder.png"));
                    gbc.insets = new Insets(0, 0, 0, 0);
                    fieldPane.add(new JLabel(new ImageIcon(img)), gbc);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(fieldPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}
  

Но это будет зависеть от потребностей и требований…

Текстовое поле с фоном

Текстовое поле с фоном

 import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.Document;

public class TextFieldBackground {

    public static void main(String[] args) {
        new TextFieldBackground();
    }

    public TextFieldBackground() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                TextFieldWithBackground field = new TextFieldWithBackground(40);
                try {
                    field.setBackgroundImage(ImageIO.read(getClass().getResource("/clouds.jpg")));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(field);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TextFieldWithBackground extends JTextField {

        private BufferedImage bg;

        public TextFieldWithBackground() {
        }

        public TextFieldWithBackground(String text) {
            super(text);
        }

        public TextFieldWithBackground(int columns) {
            super(columns);
        }

        public TextFieldWithBackground(String text, int columns) {
            super(text, columns);
        }

        public TextFieldWithBackground(Document doc, String text, int columns) {
            super(doc, text, columns);
        }

        public void setBackgroundImage(BufferedImage bg) {
            this.bg = bg;
            setOpaque(bg == null);
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            if (bg != null) {
                int x = 0;
                int y = (getHeight() - bg.getHeight()) / 2;
                while (x < getWidth()) {
                    g.drawImage(bg, x, y, this);
                    x  = bg.getWidth();
                }
            }
            super.paintComponent(g);
        }

    }

}
  

Комментарии:

1. хороший способ сделать это, но на самом деле мне нужно вот что -> dropbox.com/s/ef6tdb7hzzqacpi/Sin título.png

2. Ну, это не прозрачное поле: P

3. Нет, игнорируйте фон, мне нужно текстовое поле с синей линией без границ и фона

4. Приятно!, но теперь у меня другая проблема, когда я что-то пишу, текст находится под изображением, так что я не могу видеть, что я пишу, не могли бы вы, пожалуйста, помочь мне, специально спасибо за все

5. Что вы имеете в виду, что это «ниже» изображения?