Get the size of a Draw2d Label Figure - java

if I have a class with a private Label = new Label(""); in it and in some method i write:
private void setText(String text)
{
this.label.setText(text);
System.out.println("label size = " + this.label.getSize(0,0));
}
it will always print "label size = Dimension(0,0)". why is this? how can I obtain the size occupied by the label after setting its text? I also tried other solutions (here and method getTextBounds() as suggested in here ) but i either obtain again Dimension(0,0) or a NullPointerException, respectively.
do you have any suggestion? thanx :)

this.label.getPreferredSize() is what you're looking for. It returns the space your label would like to occupy.
But at this point the label doesn't know yet what font to use, hence the NullPointerException. Once your figure tree has been set e.g. as the content of a FigureCanvas the font should be available. Alternatively, you could explicitly set a font before calling getPreferredSize().
To add a rounded rectangle around your label, like you requested in your comment, you could do the following:
RoundedRectangle rr = new RoundedRectangle();
rr.setBorder(new MarginBorder(4));
rr.setLayoutManager(new StackLayout());
rr.add(new Label("label text"));

Related

How to create array of Panes in JavaFX(or how to control multiple similar panes)

I have a Pane that includes label1, label2, label3 and a icon(pane with image). I duplicated that Pane and now i have 10 Pane 5 at left 5 at right and i named every item different for Pane(like left1label1,left2label1,right2label3)but i don't want to use different method for every single Pane.
I tried to create an array of panes but couldn't figure it out. All i want is easy way to manage this Panes. How should i do it?
public void leftPane1Config()
{
leftPane1Label1.setText("Object");
leftPane1Label2.setText("HP:"+ hp);
leftPane1Label3.setText("EXP:"+ exp);
Image img= new Image("directory");
leftPane1Icon.setEffect(new ImageInput(img));
}
public void leftPane2Config()
{
leftPane2Label1.setText("Object");
leftPane2Label2.setText("HP:"+ hp);
leftPane2Label3.setText("EXP:"+ exp);
Image img= new Image("directory");
leftPane2Icon.setEffect(new ImageInput(img));
}
.
.And 8 other
.
I have tried to use something like this (trying to create an hierarchy but i couldn't make it :') ) but i couldn't use setText() so it didn't work.
leftPane1.getChildren().add(leftPane1Label1);
leftPane1.getChildren().get(0).setText??
Then i tried to use something like this
Pane[] leftPane= new Pane[5];
leftPane[0]= new Pane();
and again i couldn't figure it out.
It's not really clear what you're asking. Typically you would just write a method to create the panes and parameterize the parts the vary, in the usual way you do in any kind of programming.
public Pane createPane(String text1, String text2, String text3, URL image) {
Image img = new Image(image.toExternalForm());
// whatever layout you need here
VBox pane = new VBox(
new Label(text1),
new Label(text2),
new Label(text3),
new ImageView(img)
);
// any other stuff you need to do
return pane ;
}
And then of course you just call createPane() with the values you need and add the result to your scene graph however you need.

How can I get the width and the height of a JavaFX Label?

There are obviously the two methods getWidth and getHeight but they return the old label size if we just changed the Label text value.
For example, in this code, the background is not correctly resized:
Label speedLabel = new Label();
Rectangle backgroundLabel = new Rectangle();
// Some initialization
// Change the label text
speedLabel.setText(connection.getSpeed_bps()); // Sets a bigger number
// Adjust the background
backgroundLabel.setWidth(speedLabel.getWidth());
backgroundLabel.setHeight(speedLabel.getHeight());
After the initialization, my Label is like that:
And after the text change and the background adjustment, my Label is like that:
I had a look at this post but it recommends a deprecated method:
How to get label.getWidth() in javafx
The reason for returning the "old" size that the label actually doesn't get updated on the GUI in the moment when you set the textProperty of it, therefore the size is not changed.
You can listen to the widthProperty and heightProperty of the Label and resize the Rectangle in the listener:
speedLabel.widthProperty().addListener((obs, oldVal, newVal) -> {
backgroundLabel.setWidth(newVal.doubleValue());
});
speedLabel.heightProperty().addListener((obs, oldVal, newVal) -> {
backgroundLabel.setHeight(newVal.doubleValue());
});
or simply use bindings between the properties:
backgroundLabel.heightProperty().bind(speedLabel.heightProperty());
backgroundLabel.widthProperty().bind(speedLabel.widthProperty());
But if you just want to achieve a Label with some background, you don't actually need a Rectangle, just some CSS - you can check this question: FXML StackPane doesn't align children correctly
You can do it in two ways.
Approach 1:
Give the background color of your label as that of rectangle. So that whatever is the Label's size, your background rectangle will take the width accordingly.
label.setStyle("-fx-background-color:grey; -fx-padding:5");
Approach 2:
Bind the Rectangle's size according to your label size
rectangle.prefWidthProperty(label.widthProperty());
rectangle.prefHeightProperty(label.heightProperty());

Example text in JTextField

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();
}
}
});

How can I shift html-text in the JButton to the left?

I use HTML to put text into a JButton. In this way I can play with colors and text size. What I do not like is the distance from the left border of the button and the text (this separation is too large). Is there a way to decrease this distance? I think it should be some parameter in the style of the HTML code.
Sample of the code:
JButton btn = new JButton("<html><span style='color:#000000; font-size: 11pt;'>" + label + "</span></html>");
I would recommend doing this programmatically rather than attempting to do it with HTML as you'll be more likely to see consistent results across platforms.
JButton btn = ...
btn.setHorizontalTextPosition(SwingConstants.LEFT);
Then you can customise the font size by either overriding paintComponent (more work) or modifying the FontUIResource object at start-up (although this will affect the font size of all buttons); e.g.
FontUIResource f = new FontUIResource("Tahoma", Font.PLAIN, 11);
Enumeration<Object> it = UIManager.getDefaults().keys();
while (it.hasMoreElements()) {
Object key = it.nextElement();
if (UIManager.get(key) instanceof FontUIResource) {
UIManager.put(key, f);
}
}

Increasing the font size of a JTextPane that displays HTML text

Lets say that I have a JTextPane that is showing a HTML document.
I want that, on the press of a button, the font size of the document is increased.
Unfortunately this is not as easy as it seems... I found a way to change the font size of the whole document, but that means that all the text is set to the font size that I specify. What I want is that the font size is increased in a proportional scale to what was already in the document.
Do I have to iterate over every element on the document, get the font size, calculate a new size and set it back? How can I do such an operation? What is the best way?
In the example that you linked to you will find some clues to what you are trying to do.
The line
StyleConstants.setFontSize(attrs, font.getSize());
changes the font size of the JTextPane and sets it to the size of the font that you pass as a parameter to this method. What you want to to set it to a new size based on the current size.
//first get the current size of the font
int size = StyleConstants.getFontSize(attrs);
//now increase by 2 (or whatever factor you like)
StyleConstants.setFontSize(attrs, size * 2);
This will cause the font of the JTextPane double in size. You could of course increase at a slower rate.
Now you want a button that will call your method.
JButton b1 = new JButton("Increase");
b1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
increaseJTextPaneFont(text);
}
});
So you can write a method similar to the one in the example like this:
public static void increaseJTextPaneFont(JTextPane jtp) {
MutableAttributeSet attrs = jtp.getInputAttributes();
//first get the current size of the font
int size = StyleConstants.getFontSize(attrs);
//now increase by 2 (or whatever factor you like)
StyleConstants.setFontSize(attrs, size * 2);
StyledDocument doc = jtp.getStyledDocument();
doc.setCharacterAttributes(0, doc.getLength() + 1, attrs, false);
}
You could probably use css and modify only the styles font.
Since it renders th HTML as it is, changing the css class may be enough.
After exploring for a long time, I've found a way to zoom the fonts in a JTextPane that displays HTML in and out.
Here's the member function that enables a JTextPane to scale the fonts. It does not handle the images inside the JTextPane.
private void scaleFonts(double realScale) {
DefaultStyledDocument doc = (DefaultStyledDocument) getDocument();
Enumeration e1 = doc.getStyleNames();
while (e1.hasMoreElements()) {
String styleName = (String) e1.nextElement();
Style style = doc.getStyle(styleName);
StyleContext.NamedStyle s = (StyleContext.NamedStyle) style.getResolveParent();
if (s != null) {
Integer fs = styles.get(styleName);
if (fs != null) {
if (realScale >= 1) {
StyleConstants.setFontSize(s, (int) Math.ceil(fs * realScale));
} else {
StyleConstants.setFontSize(s, (int) Math.floor(fs * realScale));
}
style.setResolveParent(s);
}
}
}
}

Categories