【问题标题】:Java graphics2d: text fieldJava graphics2d:文本字段
【发布时间】:2014-10-14 04:45:26
【问题描述】:

我搜索了很多主题,但没有找到任何具体的答案。我需要在Graphics2D 上输入字段数据(如JTextFieldTextField)。

有人知道我如何创建这个组件吗?还是在Graphics2D 中添加一个文本字段(Component)?

谢谢!

【问题讨论】:

  • 我想,在直接使用图形组件时,您必须自己构建它。我不知道任何内置的文本字段。
  • 您认为为什么需要这样做?如果您确实需要这样做,请在您要扩展的任何组件上使用 KeyListener 来覆盖 paintComponent() 函数。
  • 猜测:您是否正在寻找类似stackoverflow.com/a/24851920/3182664 的东西?
  • 这是为了游戏。是的……Marco13,是这样的……让我试试

标签: java swing graphics textfield


【解决方案1】:

不太确定您要的是什么,但这里有一些代码可以在您双击时向面板添加一个文本字段。然后,您可以在文本字段中添加文本。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;

public class InvisibleTextField extends JTextField
    implements ActionListener, FocusListener, MouseListener, DocumentListener
{
    public InvisibleTextField()
    {
        setOpaque( false );
        setColumns( 1 );
        setBorder( null );
        setSize( getPreferredSize() );
        setColumns( 0 );
        addActionListener( this );
        addFocusListener( this );
        addMouseListener( this );
        getDocument().addDocumentListener( this );
    }

//  Implement ActionListener

    public void actionPerformed(ActionEvent e)
    {
        setEditable( false );
    }

//  Implement FocusListener

    public void focusLost(FocusEvent e)
    {
        setEditable( false );
    }

    public void focusGained(FocusEvent e) {}

//  Implement MouseListener

    public void mouseClicked( MouseEvent e )
    {
        if (e.getClickCount() == 2)
            setEditable( true );
    }

    public void mouseEntered( MouseEvent e ) {}

    public void mouseExited( MouseEvent e ) {}

    public void mousePressed( MouseEvent e ) {}

    public void mouseReleased( MouseEvent e ) {}

//  Implement DocumentListener

    public void insertUpdate(DocumentEvent e)
    {
        updateSize();
    }

    public void removeUpdate(DocumentEvent e)
    {
        updateSize();
    }

    public void changedUpdate(DocumentEvent e) {}

    private void updateSize()
    {
        setSize( getPreferredSize() );
    }

    public static void main(String[] args)
    {
        JPanel panel = new JPanel();
        panel.setFocusable( true );
        panel.setLayout( null );
        panel.addMouseListener( new MouseAdapter()
        {
            public void mousePressed(MouseEvent e)
            {
                JPanel panel = (JPanel)e.getSource();

                if (e.getClickCount() == 1)
                {
                    panel.requestFocusInWindow();
                }

                if (e.getClickCount() == 2)
                {
                    InvisibleTextField tf = new InvisibleTextField();
                    tf.setText("Enter Text");
                    tf.setLocation(e.getPoint());
                    panel.add( tf );
                    tf.requestFocusInWindow();
                    tf.selectAll();
                }
            }
        });

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add(new JLabel("Double Click to Add Text"), BorderLayout.NORTH);
        frame.add(panel);
        frame.setSize(650, 300);
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}

【讨论】:

  • 对不起,我可能解释得不好......如果我可以在 Graphics2D 上放置一个 InvisibleTextField 并且它工作得很好,你的代码可以帮助我。但它不起作用。当我们将 JTextField 放入图形中时,组件会保持其行为(焦点、字符接收)正常。这是我的问题。今天我有一个内置于 Graphics2D 的应用程序,我需要一个可以在其中工作的 JTextField。谢谢!
  • Today I have a application built in Graphics2D - 我想我不明白那个评论。图形被绘制到面板上。我刚刚在面板中添加了一个文本字段。所以我不明白你在问什么。如果您只想在面板上显示文本,则使用Graphics.drawstring() 方法。
  • 我有一个扩展 JPanel 并覆盖方法 paintComponent(Graphics g) 的类。将参数“g”转换为 Graphics2D 并绘制各种内容,如图像、文本、矩形等。此 JPanel 实现 MouseListener、KeyListener 和 MouseMotionListener 接口并管理用户的操作。我想要的是在这个面板中添加一个 JTextField。问题是在这种情况下 JTextField 被冻结并且不响应您的示例中的操作。
  • 所以我给了你一个工作的例子。您没有发布任何代码,所以您希望我们如何猜测您可能在做什么。因此,将我的工作代码与您的代码进行比较,看看有什么区别并修复它。如果您找不到差异,请发布 SSCCE 来说明问题。
  • 对不起家伙... :'( 我的帖子坏了...感谢您的帮助,我尝试使用此处发布的所有建议。最后,我选择创建一个组件。请参阅最后一个答案。再次感谢您!
【解决方案2】:

你帮了我很多。在测试了这里发布的几个示例之后,我选择创建一个组件。请参阅下面的代码。

package br.com.linu.vectortown.base.screen.textfield;

import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.Serializable;

import br.com.linu.vectortown.base.screen.button.command.ICommand;
import br.com.linu.vectortown.base.screen.button.command.ISendCommand;
import br.com.linu.vectortown.base.screen.font.GameFont;
import br.com.linu.vectortown.base.screen.graphics.IGenericGraphics;
import br.com.linu.vectortown.base.util.PropertiesUtil;

public class GameTextField implements Serializable {

    private static final long serialVersionUID = -8273087631607158422L;

    private static final String CURSOR = "|";

    private StringBuffer buffer;
    private String showableText;
    private int index;
    private GameFont font;
    private int maxLength;
    private float alpha;

    private Rectangle rectangle;
    private Point textPoint;

    private String validCharacters;
    private int padding;

    private int cursorDelay;
    private int countDelay;
    private boolean cursor;
    private int cursorLength;

    private boolean focus;

    private ICommand clickedCommand;
    private ISendCommand returnKeyCommand;
    private ICommand escapeKeyCommand;

    public GameTextField(GameFont font, Rectangle rectangle, int maxLength) {

        /* Get default parameters */
        this.validCharacters = PropertiesUtil.INSTANCE.valorPor("game.text.field.valid.characters");
        this.padding = PropertiesUtil.INSTANCE.inteiroPor("game.text.field.padding");
        this.cursorDelay = PropertiesUtil.INSTANCE.inteiroPor("game.text.field.cursor.delay");
        this.alpha = PropertiesUtil.INSTANCE.floatPor("game.boxlog.text.field.background.alpha");

        /* Set attributes with constructor parameters */
        this.font = font;       
        this.rectangle = rectangle;

        /* Set text point */
        int x = this.rectangle.x + this.padding;
        int y = this.rectangle.y + 
                this.font.getSpacing( this.validCharacters ).height + 
                this.font.getFineTuning() -
                this.padding;       
        this.textPoint = new Point( x , y );

        /* Create variables to control buffer */
        this.buffer = new StringBuffer();
        this.showableText = "";
        this.maxLength = maxLength;     
        this.clearIndex();

        /* Create variables to control cursor */
        this.countDelay = 0; 
        this.cursor = false;
        this.cursorLength = this.font.getSpacing( CURSOR ).width;

        /* Starts without focus */
        this.focus = false;
    }

    private void clearTextField() {
        this.focus = false;
        this.buffer = new StringBuffer();
        this.showableText = "";     
        this.clearIndex();
    }

    private int getAdjustedTextWidth(String text) {
        return font.getSpacing(text).width + cursorLength + (2 * padding);
    }

    public void setClickedCommand(ICommand command) {
        this.clickedCommand = command;
    }

    public void setReturnKeyCommand(ISendCommand command) {
        this.returnKeyCommand = command;
    }

    public void setEscapeKeyCommand(ICommand command) {
        this.escapeKeyCommand = command;
    }

    public synchronized boolean wasClicked(int mouseX, int mouseY) {
        focus = rectangle.contains( new Point( mouseX , mouseY ) );
        if ( focus ) {
            this.clickedCommand.execute();
        }
        return focus;
    }

    public synchronized void onFocus() {
        focus = true;
    }

    /**
     * ENTER
     */
    public synchronized void returnKey() {
        if ( buffer.length() > 0 ) {
            String value = this.buffer.toString();
            clearTextField();
            this.returnKeyCommand.setParameters(value);
            this.returnKeyCommand.execute();
        } else {
            clearTextField();
            this.escapeKeyCommand.execute();
        }       
    }

    /**
     * ESC
     */
    public synchronized void escapeKey() {  
        clearTextField();
        this.escapeKeyCommand.execute();
    }

    private void clearIndex() {
        this.index = 0;
    }

    private int getIndex() {
        return index;
    }

    private void increaseIndex() {
        index++;
    }

    public synchronized void delete() {
        if ( buffer.length() > 0 ) {
            clearIndex();
            buffer.deleteCharAt( buffer.length() - 1 );

            /* Get showable text with index */
            showableText = buffer.substring( getIndex() , buffer.length() );

            /* Adjust showable text if necessary */
            while ( getAdjustedTextWidth(showableText) > rectangle.width ) {
                increaseIndex();
                showableText = buffer.substring( getIndex() , buffer.length() );
            }
        }
    }

    public synchronized void add(char character) {

        /* Validate size */
        if ( buffer.length() >= maxLength ) {
            return;
        }

        /* Validate character */
        if ( validCharacters.indexOf( character ) == -1 ) {
            return;
        }

        /* Add char in buffer */
        buffer.append( character );

        /* Get showable text with index */
        showableText = buffer.substring( getIndex() , buffer.length() );

        /* Adjust showable text if necessary */
        while ( getAdjustedTextWidth(showableText) > rectangle.width ) {
            increaseIndex();
            showableText = buffer.substring( getIndex() , buffer.length() );
        }
    }

    public synchronized void draw(IGenericGraphics graphics) {      

        if ( focus ) {
            /* Draw component */
            graphics.drawFilledRectangle(Color.white, rectangle, alpha);

            /* Verifier if can draw cursor */
            countDelay++;
            countDelay = countDelay % cursorDelay;          
            if ( countDelay == 0 ) {
                cursor = !cursor;
            }

            /* Set text to draw */
            String text = showableText + ( ( cursor ) ? CURSOR : "" );

            /* Draw */
            graphics.drawText(font, textPoint.x, textPoint.y, text);
        }
    }

}

对不起,如果我没有提出任何问题的代码。我真正需要的是一个完全在 Graphics2D 上运行的 TextField。在这个应用程序中,我获得了 JPanel 的 Graphics2D,并手动更改了它们的行为(使用键和鼠标侦听器)。当我在这个 JPanel 中放置一个 JTextField 时,它不能正常工作。这就是问题所在。

由于我没有找到好的选择,我决定创建一个自定义组件(上面的代码)。重要的是方法 draw() 和 add()。在 draw() 方法中,我绘制了一个矩形和在 add() 方法中逐个字符输入的文本。现在这正在工作......

感谢大家的帮助!

【讨论】:

    猜你喜欢
    • 2011-05-04
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    相关资源
    最近更新 更多