问题
I searched for many topics but did not find any with a concrete answer. I need a field data input on the Graphics2D
(like the JTextField
or TextField
).
Does anyone know how I can create this component? Or put a text field (Component
) in Graphics2D
?
Thank you!
回答1:
Not really sure what you are asking for, but here is some code that will add a text field to a panel when you double click. You can then add text to the text field.
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);
}
}
回答2:
you helped me a lot. After testing a few examples posted here, I chose to create a component. See the code below.
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);
}
}
}
Sorry if I did not put any code in question. What I really needed was a TextField any that ran entirely on a Graphics2D. In this application I get the Graphics2D of JPanel and I change their behavior manually (with keys and mouse listeners). When I put a JTextField in this JPanel, it did not work normally. This was the problem.
As I did not get a good alternative, I decided to create a custom component (code above). What matters is the methods draw() and add(). In the draw() method I drew a rectangle and the text that was entered character by character in the add() method. For now this is working ...
Thanks for the help everyone!
来源:https://stackoverflow.com/questions/25411278/java-graphics2d-text-field