Example text in JTextField - java

I am looking for a way to put example text into a swing JTextField and have it grayed out. The example text should then disappear as soon as any thing is entered into that text field. Some what similar to what stackoverflow does when a user is posting a question with the title field.
I would like it if it was already a extended implementation of JTextField so that I can just drop it in as a simple replacement. Anything from swingx would work. I guess if there is not an easy way to do this my option will probably be to override the paint method of JTextField do something that way maybe.
Thanks

The Text Prompt class provides the required functionality without using a custom JTextField.
It allows you to specify a prompt that is displayed when the text field is empty. As soon as you type text the prompt is removed.
The prompt is actually a JLabel so you can customize the font, style, colour, transparency etc..:
JTextField tf7 = new JTextField(10);
TextPrompt tp7 = new TextPrompt("First Name", tf7);
tp7.setForeground( Color.RED );
Some examples of customizing the look of the prompt:

If you can use external librairies, the Swing components from Jide software have what you are looking for; it's called LabeledTextField (javadoc) and it's part of the JIDE Common Layer (Open Source Project) - which is free. It's doing what mklhmnn suggested.

How about initialize the text field with default text and give it a focus listener such that when focus is gained, if the text .equals the default text, call selectAll() on the JTextField.

Rather than overriding, put a value in the field and add a KeyListener that would remove the value when a key stroke is registered. Maybe also have it change the foreground.
You could wrap this up into your own custom JTextField class that would take the default text in a constructor.

private JLabel l;
JPromptTextField(String prompt) {
l = new JLabel(prompt, SwingConstants.CENTER);
l.setForeground(Color.GRAY);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (this.getText().length() == 0) {
// Reshape the label if needed, then paint
final Rectangle mine = this.getBounds();
final Rectangle its = l.getBounds();
boolean resized = (mine.width != its.width) || (mine.height != its.height);
boolean moved = (mine.x != its.x) || (mine.y != its.y);
if (resized || moved)
l.setBounds(mine);
l.paint(g);
}
}

You can't do that with a plain text field, but you can put a disabled JLabel on top of the JTextField and hide it if the text field gets the focus.

Do it like this:
Define the string with the initial text you like and set up your TextField:
String initialText = "Enter your initial text here";
jTextField1.setText(initialText);
Add a Focus Listener to your TextField, which selects the entire contents of the TextField if it still has the initial value. Anything you may type in will replace the entire contents, since it is selected.
jTextField1.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
if (jTextField1.getText().equals(initialText)) {
jTextField1.selectAll();
}
}
});

Related

How to know in which JTextPane the cursor is?

I have several JtextPanes and I want to create a method that set the value of a variable to the name of the TextPane which has been clicked because another methond is going to use it. There's also a button that adds a new jTextPane when the user clicks on it and I want those new TextPanes to inherit that method. Or if you know a simpler way to achieve that I'm open to read you. Let me know if you need more information or more code.
static JTextPane focus;
private void redColorActionPerformed(java.awt.event.ActionEvent evt) { //Ths is the method that works with the focus variable. It changes the color of the text in the clicked textpane.
TextEditor.cambiarColor(new java.awt.Color(255, 0, 0), focus);
}
It sound like you want to know the current Swing JTextPane component under the current mouse position? Then try to
Get current Mouse position
Point position = MouseInfo.getPointerInfo().getLocation();
Get the component under the mouse location
Component c = SwingUtilities.getDeepestComponentAt(
the-root-component,
position.getX(),
position.getY()
);
if (c instanceof JTextPane) {
// do your logic
}

How to make a textarea filled with text (label) every time the button pressed?

I'm trying to make a text area record that every time the button is press, it means that it has been recorded and should be showing record1, record2, record3, etc. on it.
My goal is that, every button is pressed it will add text to the text area with different text label so that no redundancy.
I tried it with my own with this:
private void btnReqstRefreshActionPerformed(java.awt.event.ActionEvent evt) {
JLabel labelthis = new JLabel("record1");
label.setSize(label.getPreferredSize());
TextArea1.add(label);
TextArea1.revalidate();
TextArea1.repaint();
}
I know it is wrong, but is it possible?
text area is like a mini text editor - you add text to it not other components. Instead of adding labels - just add the text. Something like:
TextArea1.setText(TextArea1.getText() + "record1")
This should append record1 to the existing text in the text area.
According to my experience this is possible.
`private void btnReqstRefreshActionPerformed(java.awt.event.ActionEvent evt) {
i++;//i class level variable(static) to avoid redundancy
//labelThis initialized earlier should be accessible here
String oldText = labelThis.getText().toString();
oldText += "record "+i;
labelThis.setSize(labelThis.getPreferredSize());
TextArea1.add(labelThis);
TextArea1.revalidate();
TextArea1.repaint();
}`

using LayoutClickListener to terminary replace components

I have grid layout witch some fields added like that:
private Component userDetailsTab(final User user) {
final GridLayout details = new GridLayout(2, 1);
details.setMargin(true);
details.setSpacing(true);
details.addComponent(createDetailLabel(Messages.User_Name));
final Component username = createDetailValue(user.getName());
details.addComponent(username);
...
I have also Layout click listener which replace labels on text field, it looks like that:
final TextField tf = new TextField();
details.addListener(new LayoutClickListener() {
private static final long serialVersionUID = -7374243623325736476L;
#Override
public void layoutClick(LayoutClickEvent event) {
Component com = event.getChildComponent();
if (event.getChildComponent() instanceof Label) {
Label label = (Label)event.getChildComponent();
details.replaceComponent(com, tf);
tf.setValue(label.getValue());
}
}
});
In future I want to enable click on label, edit it and write changes to database after clicking somewhere else (on different label for example).
Now when I click on 1st label and then on 2nd label, effect is: 1st has value of 2nd and 2nd is text field witch value of 2nd. Why it's going that way? What should i do to after clicking on 1st and then 2nd get 1st label witch value of 1st?
You don't need to swap between Labels and TextFields, you can just use a TextField and style it look like a Label when it's not focused.
When I tried to create click-to-edit labels, it created a ton of extra work for me. I'd discourage it (and do as Patton suggests in the comments).
However, if you're going to insist on trying to create in-place editing, you will want to do the following:
Create a new class that extends a layout (e.g. HorizontalLayout), which can swap out a label for a text field
use LayoutClickListener to removeComponent(myLabel) and addComponent(myTextField)
use BlurListener to swap back to the label
use ValueChangeListener on the text field to copy its value to the label
This is a still a bad idea because:
Users cannot see affordances as easily (they can't tell what's editable)
Users cannot use the keyboard to tab to the field they want to edit
It adds unncessary complexity (maintenance time, etc).
I would recommend, if you want in-place editing, just show the text field, and save the new value with the BlurListener.

JTextField show '...' when content is too long

I'm trying to make JTextField display dots when its content is longer then display area. I would like to have the same behaviour like in JTable, where when I resize column the text inside changes - when its to long only begining of it is displayed and then there are three dots (to see what I have in mind please run first example from this link and change column size - I'm not allowed to post images because I'm new here;) )
Is is possible? Only solution that I have in mind is extending JTextField with a class that will have additional field oryginalText and will behave like that (didn't test it, it's just a proposal, dimension of the JtextField will not change):
import javax.swing.JTextField;
public class MyTextField extends JTextField {
private String oryginalText;
private int length;
#Override
public void setText(String text) {
oryginalText = text;
if (oryginalText.length() > length)
super.setText(oryginalText.substring(0, length - 2) + "..");
else
super.setText(oryginalText);
}
}
any ideas?
Over your idea of extending JTextField and storing the original (non trimmed) value:
Show the textfield as disabled (or not editable) and with trimmed text. When the user clics the textfield make it enabled/editable and show the whole original text.
Then again when the user press enter or the focus exits of the textfield: disable/not editable and trimmed text.

How do I use requestFocus in a Java JFrame GUI?

I am given an assignment but I am totally new to Java (I have been programming in C++ and Python for two years).
So we are doing GUI and basically we extended JFrame and added a couple fields.
Say we have a field named "Text 1" and "Text 2". When user presses enter with the cursor in Text 1, move the focus to Text 2. I tried to add
private JTextField textfield1() {
textfield1 = new JTextField();
textfield1.setPreferredSize(new Dimension(200, 20));
textfield1.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
textfield1text = textfield1.getText().trim();
textfield1.setText(textfield1text);
System.out.println(textfield1text);
textfield1.requestFocus();
}
});
return textfield1;
}
But that doesn't work at all.
I noticed that requestFocus is not recommended, and instead one should use requestFocusWindows. But I tried that too. Upon some readings it seems like I have to do keyboard action and listener? But my teacher said it only requires 1 line...
Well, you have textfield1.requestFocus(), but your description would imply you need textfield2.requestFocus(). (that's 2).
Another option might be to use:
textField1.transferFocus();
This way you don't need to know the name of the next component on the form.

Categories