Запретить текст за пограничным объектом - PullRequest
1 голос
/ 13 июня 2019

У меня есть JTextField, в котором я хочу отобразить значок проверки справа, однако, если текст достаточно длинный, он запускается под значком:

text behind icon

Как можно избежать этого, когда значок отображается в JTextField?

Вот простая программа, которая воспроизводит проблему:


import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;

public final class Borders extends JFrame {

    public Borders() {
        JTextField field = new JTextField();
        Border outsideBorder = field.getBorder();
        field.setBorder(new CompoundBorder(outsideBorder, new AbstractBorder() {

            @Override
            public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
                Insets insets = outsideBorder.getBorderInsets(c);
                Font font = c.getFont();
                FontMetrics metrics = c.getFontMetrics(font);
                int by = (c.getHeight() / 2) + (metrics.getAscent() / 2) - insets.top;
                int bw = Math.max(2, insets.left); // border width
                int iw = metrics.stringWidth("=="); // icon width
                int bx = x + width - (Math.round(iw * 1.5f) + (bw * 2)) + 2;
                g.translate(bx, by);
                g.setColor(Color.RED);
                g.setFont(c.getFont().deriveFont(Font.BOLD, font.getSize()));
                g.drawString("==", x + (iw / 2), y);
            }

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

        }));
        this.add(field);
        this.pack();
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            new Borders().setVisible(true);
        });
    }

}

Это результат примера программы:

enter image description here

Код, сгенерировавший первое изображение, находится на GitHub .

1 Ответ

0 голосов
/ 13 июня 2019

Вы должны реализовать метод getBorderInsets. Как то так:

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;

public final class Borders extends JFrame {

    public Borders() {
        JTextField field = new JTextField();
        Border outsideBorder = field.getBorder();
        field.setBorder(new CompoundBorder(outsideBorder, new AbstractBorder() {

            @Override
            public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
                Insets insets = outsideBorder.getBorderInsets(c);
                Font font = c.getFont();
                FontMetrics metrics = c.getFontMetrics(font);
                int by = (c.getHeight() / 2) + (metrics.getAscent() / 2) - insets.top;
                int bw = Math.max(2, insets.left); // border width
                int iw = metrics.stringWidth("=="); // icon width
                int bx = x + width - (Math.round(iw * 1.5f) + (bw * 2)) + 2;
                g.translate(bx, by);
                g.setColor(Color.RED);
                g.setFont(c.getFont().deriveFont(Font.BOLD, font.getSize()));
                g.drawString("==", x + (iw / 2), y);
            }

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

            @Override
            public Insets getBorderInsets(Component c, Insets insets) {
                insets.right = 15;
                return insets;
            }
        }));
        this.add(field);
        this.pack();
        this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        this.setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            new Borders().setVisible(true);
        });
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...