java - 如何在自定义 JTextField 中绘制光标?

标签 java swing jtextfield caret

我创建了一个圆形的 JTextField,它覆盖了 paintComponent(g: Graphics) 方法。形状和文本正确绘制,但我还没有实现任何显示光标的内容。

How can I achieve that?

编辑: super.paintComponent(...) 不是解决方案。如果我使用它,那么您可以看到其他绘制组件的边缘。

这是到目前为止的代码(正如所描述的,没有渲染光标!)

@Override
protected void paintComponent(Graphics g) {

    //TODO entfernen
    //super.paintComponent(g);

    if(g instanceof Graphics2D) {
        Graphics2D graphics = (Graphics2D) g;
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        //Draw button background
        graphics.setColor(getBackground());
        graphics.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, arcRadius, arcRadius);

        this.paintText(graphics);

    }
}

protected final void paintText(@NotNull Graphics2D g) {
    //Draw font
    g.setColor(getForeground());
    if (this.getFont() != null && this.getText() != null) {
        FontMetrics fm = getFontMetrics(getFont());
        g.setColor(this.getForeground());
        g.drawString(this.getText(), ((this.getWidth() / 2) - (fm.stringWidth(this.getText()) / 2)),
                ((this.getHeight() / 2) + fm.getMaxDescent()));
    }
}

编辑2: 这是当我调用 super.paintComponent(...) 时的结果:

super component visible

如您所见, super 组件是可见的。这就是为什么我不调用 super 方法。

有人有使用 Caret 的经验吗?很确定这是正确的方法...

最佳答案

调用 super.paintComponent(Graphics g) 永远不会错!

与 OP 不同,我将提供一个最小的可运行示例,显示带有圆角的自定义 JTextField。

首先,这是我必须创建的 GUI。

Sample GUI

如您所见,黄色的自定义 JTextField 有圆角。

这是我所做的最小的、可运行的示例。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class CustomJTextField implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new CustomJTextField());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Custom JTextField");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.setPreferredSize(new Dimension(400, 160));

        Font font = panel.getFont().deriveFont(32F);

        JLabel label = new JLabel("Something");
        label.setHorizontalAlignment(JLabel.CENTER);
        label.setFont(font);
        panel.add(label, BorderLayout.BEFORE_FIRST_LINE);

        QTextField sampleField = new QTextField(panel, 10);
        sampleField.setBackground(Color.YELLOW);
        sampleField.setFont(font);
        panel.add(sampleField, BorderLayout.CENTER);

        frame.add(panel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public class QTextField extends JTextField {

        private static final long serialVersionUID = 1L;

        private int arcRadius = 40;

        private Container container;

        public QTextField(Container container, int length) {
            super(length);
            this.container = container;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D graphics = (Graphics2D) g;
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            // Draw button background
            graphics.setColor(container.getBackground());
            graphics.fillRect(0, 0, getWidth(), getHeight());
            graphics.setColor(getBackground());
            graphics.fillRoundRect(20, 20, getWidth() - 40, getHeight() - 40, arcRadius, arcRadius);

            this.paintText(graphics);

        }

        private void paintText(Graphics2D g) {
            // Draw font
            g.setColor(getForeground());
            if (this.getFont() != null && this.getText() != null) {
                FontMetrics fm = getFontMetrics(getFont());
                g.setColor(this.getForeground());
                g.drawString(this.getText(), ((this.getWidth() / 2) - (fm.stringWidth(this.getText()) / 2)),
                        ((this.getHeight() / 2) + fm.getMaxDescent()));
            }
        }
    }

}

关于java - 如何在自定义 JTextField 中绘制光标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60938308/

相关文章:

java - 如何将 JAR 文件添加到 IBM WebSphere 服务器中的项目类路径?

java - 有没有读取/var/spool/mail/files的库?

java - 当面板已满时将滚动面板添加到 jpanel (java)

java - ActionListener 和 IF 语句出现问题

java - CompletableFuture join() 方法出现巨大延迟

java - 将 JSON 响应解析为列表

java - 将 Action 事件添加到外观菜单项

java - 在两个 GUI 类之间传输 String 时出现 NullPointerException

java - 无法在 JTextfield 中输入文本

java - 如何从 JTextField 中获取 Float 值?