I have a Swing Application where a user has to Input Some information. I need the cursor By default to be at Position 10 of the JtextField: I have tried these Two Methods but none of them has worked for me:
JTextField text = new JTextField(" ", 50);
text.setHorizontalAlignment(10)
The other one I have tried is
JTextField text = new JTextField(" ", 50);
text.setCaretPosition(10)
Is there really a way to do what am trying?
Try this:
text.getCaret().setDot(10);
Doesn't the problem come from your JTextField containing an empty String ?
If you want the cursor to be at a set position, this position should be reachable, i.e having a String containing 10 blank spaces.
PS : I think setCaretPosition is the right method here.
Related
Introduction to the problem
It seams impossible to change a Veriable in a event (like so for example button.setOnAction(e -> { x = x+2});) and I can see why, but what if that's exactly what I need? It's actually not the first time that I needed to do that, but last time I got around it by saving the changed property directly to a file.
This time I used a really tricky trick to create a 'fake variable' by using the text in an invisibe TextField as my veriable. It works, that's not the problem, but I'd like to have a more 'elegant' salution :D
Friuts of my research
The only two salutions I could find were to either declare a Variable as a class member (which I don't want to do seeing that I already have six of them and don't want to tripple that amount) or to use seperate classes. (I found that here: How to change a variable when a button has been clicked in JavaFx )
The programm
Here is the code of my popup window (I'll spare you of the rest of my stupid programm ^^ ), I'll explain what it does after the codebox. (Note that props is a properties object and one of the mentioned class members as well as propPath (meaning I declared it at the very top of the programm so that it can be accessed from every function)):
private void createNewBuff() throws Exception {
Stage popupStage = new Stage(StageStyle.UTILITY);
popupStage.initModality(Modality.APPLICATION_MODAL);
popupStage.setTitle("Creating a new Buff");
popupStage.setMinWidth(400);
popupStage.setMinHeight(300);
GridPane layoutGP = new GridPane();
layoutGP.getColumnConstraints().addAll(
new ColumnConstraints(200), //TextField column col 0
new ColumnConstraints(10), //Gab column col 1
new ColumnConstraints(60), //tf manips column col 2
new ColumnConstraints(30), //Gab column col 3
new ColumnConstraints(80)); //Main buttons col col 4
TextField tfName = new TextField("Unknown Buff");
tfName.setPromptText("Name of the Buff, e.g. \"Unknown Buff\"");
Label lblName = new Label("Name");
layoutGP.add(tfName, 0, 0);
layoutGP.add(lblName, 2, 0);
TextField varTF = new TextField();
TextField tfEffect = new TextField();
tfEffect.setPromptText("Effect of the Buff, e.g. \"+10 LP\"");
Button btnAdd = new Button("Add");
btnAdd.setOnAction(e -> {
String input = tfEffect.getText();
String[] comps = input.split(" "); //components
if (Array.getLength(comps) == 2) {
if (input.contains("+")) {
varTF.setText(varTF.getText() + input + ";");
layoutGP.add(new Label(input), 0, 1 + Array.getLength(varTF.getText().split(";")));
} else if (input.contains("-")) {
varTF.setText(varTF.getText() + input + ";");
layoutGP.add(new Label(input), 0, 1 + Array.getLength(varTF.getText().split(";")));
}
}
});
layoutGP.add(tfEffect, 0, 1);
layoutGP.add(btnAdd, 2, 1);
Button btnDone = new Button("Done");
btnDone.setOnAction(e -> {
int buffNumber = 1;
while (props.containsKey("Buff-" + buffNumber + "-name"))
buffNumber++;
props.setProperty("Buff-" + buffNumber + "-name", tfName.getText());
props.setProperty("Buff-" + buffNumber + "-effect", varTF.getText());
try {
FileOutputStream streamOut = new FileOutputStream(propPath);
props.store(streamOut, null);
streamOut.close();
popupStage.close();
}catch (IOException someE){/*something meaningful*/}
});
btnDone.setMaxWidth(Double.MAX_VALUE);
Button btnCancel = new Button("Cancel");
btnCancel.setOnAction(e -> popupStage.close());
btnCancel.setMaxWidth(Double.MAX_VALUE);
layoutGP.add(btnDone, 4, 0);
layoutGP.add(btnCancel, 4, 1);
layoutGP.setAlignment(Pos.TOP_CENTER);
Scene popupScene = new Scene(layoutGP);
popupStage.setScene(popupScene);
popupStage.showAndWait();
}
I wanted to post a picture there of how it looks once you start it and another of how it looks after you used it, but my reputation is still to low ^^
Therefor I'll provide the links to the pictures: Befor something was done http://i.imgur.com/Wx3nIEX.png After it's used http://i.imgur.com/5QNmWP6.png
What the programm does
It's pretty strait forward actually: my main programm is a character sheet and with that popup you can add a buff to it (later I'll make it so that the effects of the buff get calculated into the values of the sheed, but one step at a time ^^ ). You can set the name of the buff you want to create ("Unknown Buff" is the standart in case you forgett to set one) and then you can simply add defferent effects by writing tem into the TextField and then pressing the 'Add' button. They will list themself top to bottom in the free space. They will also, behind the scenes, save themself as one large string into a hidden TextField to make figuring out in which line each individual Effect has to be displayed and to save it to the properties file afterwards. (and that salution with the undisplayed textfield is exactly the trick I want to remove and turn into a more 'elegant' salution)
Detailed explanaition of the code
At first the Stage is created. Then the layout is made in form of a gridpane und the column sizes are set (every second column is for spacing reasons). After that I'm creating the line for the name (the label and the textfield) and also my tricky textfield that's used as a String variable. Now I'm creating the effect textfield and add button, as well as the event for the button: at first it turns the input from the textfield into a easier to read name and splits it into it's components (at first I used tfEffect.getText() and tfEffect.getText().split(" ") inside the code below, but that was really messy) now I have if statements to verify it and make sure that the Effect is in the right format (that format beeing the amount a certain stat is raised or lowerd, consisting of either a plus or a minus symbol at the beginning and a number after that; followed by a space and then the index of the stat (I haven't been able to implement verifying if the typed thing actually is a valid stat, maybe that'll be content of a future question ;D )). After verifying the programm it adds the effect below all the others. If you're done and happy with you're buff you can click the Done button, it will first look up how many Buffs already exist, then assign the new on a number and save it all to the properties file. The cancel button with of course just cancel it and at the bottom I'm setting the scene and calling the stage.
What I'm hoping for with this question
Now I think you have a pretty clear idea of what I need to do and why I couldn't find a better salution then using a hidden TextField as a variable and I hope it's because I'm a beginner and not because there actually is no better way of doing it ^^
Also if you actually read all of this you may found one or two things I can improve besides that, but that would be the special bonus ;D
I am new to java swing and I am creatin a Jlabel as follows :
JLabel Lport = new JLabel ("Port: ");
final JTextField Tport = new JTextField ("1883", 10);
what i want to do is to get the name of the label as a string because i want to use it in a switch-case, so i need to get the label name or a unique identifier of that label, some thing like an ID as it exists in Android, i tried the method ",getAction.toString", ".getName" but none of them displayed the name of the labe, which is according to the code posted is "Port: ". please see my attempts below:
if ( (isIPReady(Tip)) && (isPortReady(Tport)) ) {
Thread mqttThread = new Thread(MQTTRunnable, MQTT_THREAD);
mqttThread.start();
System.out.println("Action: " + Tport.get); //here i do not know which method to use
setViewEnableState(Bconnect, true);
}
The short answer is to use JLabel#getText which will return the text which is displayed by the JLabel.
An alternative could be to store your own key-value pair into the different JComponent instances. Each JComponent allows to put and retrieve client properties. A copy-paste from the class javadoc:
Support for component-specific properties. With the
putClientProperty(java.lang.Object, java.lang.Object) and
getClientProperty(java.lang.Object) methods, you can associate
name-object pairs with any object that descends from JComponent.
This would allow you to write:
private static final String ID_KEY = "MyUniqueIDKey";
JLabel label = new JLabel( "Whatever" );
label.putClientProperty( ID_KEY, "labelName" );
and then later on
String labelName = (String) label.getClientProperty( ID_KEY );
Note that this works with any JComponent, including JLabel and JTextField instances like the ones you are using in your code.
JLabel's name is different than the text it displays. To get the text from a JLabel, use getText().
You mention you want the name of the label but in your example you're calling a get on your textfield.
This applies to both a textfield and a label anyway.
That constructor sets the initial text that will display in the text field (or label).
If you want to set a name, you must first set it using setName() then use getName().
I'm having trouble trying to get a linebreak included in a Stringbuilder to appear in a JLabel.
I've found a couple of similar problems solved here, e.g. [here] Problems to linebreak with an int in JLabel and [here] How do I append a newline character for all lines except the last one? , along with a few others but none of them seem to work for me.
When printing to System.out, it works fine and I get a new line each time but when passed to a JLabel, everything appears as one line.
Here's the current version of the code, which has attempted to append a newline character, as well as including one in the main declaration. Neither has any effect when passed to the JLabel:
public void layoutCenter() {
JPanel central = new JPanel();
add(central, BorderLayout.CENTER);
JTabbedPane tabs = new JTabbedPane();
this.add(tabs);
// memory tab
StringBuilder mList = new StringBuilder();
memLocList = new Memory[MEM_LOCATIONS]; //Memory is a separate class
for (int i = 0; i < memLocList.length; i++) {
mList.append("\n");
memLocList[i] = null;
mList.append("Memory location: " + i + " " + memLocList[i] + "\n");
}
System.out.println(mList.toString());
JComponent memTab = makeTextPanel(mList.toString());
tabs.addTab("Memory", memTab);
}
protected JComponent makeTextPanel(String text) {
JPanel panel = new JPanel(false);
JLabel filler = new JLabel(text);
panel.add(filler);
return panel;
}
I've also tried using System.getProperty(line.separator) with similar results and can't think of anything else to try so thought I'd appeal for help here.
Thanks,
Robert.
-EDIT-
Thanks to mKorbel, changing the JLabel to a JTextPane solved it.
The two lines in question are:
JTextPane filler = new JTextPane();
filler.setText(text);
Thanks again to everyone.
JLabel isn't designated to held multilines document, there are two choices (by accepting newline or tab by default)
if document could not be decorated or styled somehow then to use JTextArea
in the case document could be decorated or styled somehow then to use JEditorPane or JTextPane
You're going to have to use <html> and <br> to get line breaks in a JLabel Swing component.
If you absolutely must use JLabel, then I suggest using one for each line.
You can make a JLabel have mulitple lines by wrapping the text in HTML tags and using br tags to add a new line.
If you news auto wrapping I suggest using a JTexrArea. You can make it uneditable and style it so it looks like a label.
You can look at this tutorial:
http://docs.oracle.com/javase/tutorial/uiswing/components/html.html
One of the example is using html to make it two lines for a JButton text. It should be very similar.
Hi Everyone thanks for taking the time to look at my question.
I would like to use the JText field I have created to display the values of a tree map which contains all the employees: ID numbers (as the key in the map)as well as an Employee object which contains a to string method of all the employee details.
the system seems to be working fine because when I print to the console (CMD) it works fine and prints out all the values in the MAP but when I try print it to a JText box it only prints one object (one employee) from the entire list.
I believe the issue lies with my for loop i am using to access all the details.
the issue lies with this line of code:
writeStrings.setText(writeStrings.getText()+" "+dEmp);
This is the code in its entirety:
public void chooseEmpToAdd()
{
JFrame frameAllEmps = new JFrame();
frameAllEmps.setSize( 450, 140 );
frameAllEmps.pack();
frameAllEmps.setVisible(true);
int x = 0;
System.out.println("ALL Emps from the tree map");
for(int key:employeeMap.keySet())
{
JTextField writeStrings;
writeStrings = new JTextField(20);
Employee dEmp = employeeMap.get(key);
System.out.println("Employe no :" +x+": "+dEmp);
writeStrings.setText(writeStrings.getText()+" "+dEmp);
frameAllEmps.add(writeStrings);
x++;
}
}
writeStrings = new JTextField(20);
You create new JTextField component on every iteration and add it to container.
JFrame uses BorderLayout as a default layout.
This layout puts your JTextField component in the center (frameAllEmps.add(writeStrings)). So you lost previous added JTextField and see only last JTextField component.
What would be an easy way to set the background color of all characters from some start to an end position in Java.
Eg:
red background from position D(4) to J(10)
String alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
Many thanks in advance.
Edit:
Oh no, 2 '-'? Ok here is what I'm doing.
JTextArea textArea = new JTextArea("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
textArea.setFont(new Font("Courier", Font.PLAIN, 16));
//then I want red background from position D(4) to J(10)
please read Using Text Components and tons examples for that
look here for excelent workaround
Split the String into 3 separate Strings.
String a = alpha.substring(0,4);
String b = alpha.substring(4,11);
String c = alpha.substring(11);
Then display a,b, and c next to each other while only formatting b as desired.