Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 5655
  • Last Modified:

How to make a JLabel proportionally change size to fit a given string?

HI, Dear All:

I need to create a JLabel derived class that can accept a text string in its constructor to create a JLabel

Public class MyLabel extends JLabel {

//Constructor accept a text string
 MyLabel(String text){
        super();
        int lgth=text.length() * 10;
         setBounds(1,1,lgth,20);
        setText("text");
        setForeground(Color.black);
        setOpaque(true);
        setBackground(Color.red);
        setHorizontalAlignment(CENTER);
        setBorder(BorderFactory.createLineBorder(Color.black));
       }
     ...
}
         
Notice in the above code, I have to calculate the length of the given string and then use setBounds(1,1,lgth,20) to make it visible and sort of fit the text string into JLabel. I also add the JLabel component to a JPanel. My questions are:
1. Why I need setBounds to make it visible (Not visible if I take out the setBounds())
2. Is there anyway to make a JLabel (automatically if will) proportionally change size to fit a given string? (of couse with the default font and font size)? So that I do not have to calculate the length of the text string and use setBounds()

Alternatively, if JLabel can not do the No.2, is there any other component can have this feature?

Thanks a lot,

yi02

0
yi02
Asked:
yi02
  • 7
  • 7
  • 6
  • +1
4 Solutions
 
zzynxSoftware engineerCommented:
>> Why I need setBounds to make it visible
What's the layout of your JPanel?

>> Is there anyway to make a JLabel (automatically if will) proportionally change size to fit a given string?
That's the standard behaviour of JLabel.
But the used layout (manager) can decide not to show the JLabel in full length
0
 
StillUnAwareCommented:
Can't you after changing the label text, repack the panel, and refresh the swing
0
 
zzynxSoftware engineerCommented:
Try having a JFrame containing a JPanel (having the FlowLayout) containg a JLabel.
You'll see that the width of the JLable will be adapted to the length of the containing string.
(as long as it is not wider than the JFrame)

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
zzynxSoftware engineerCommented:
Consider this little demo app.
Run it and press the button and see the label adapt.

/*
 * LabelTest.java
 *
 */

import javax.swing.*;

/**
 *
 * @author  zzynx
 */

public class LabelTest extends javax.swing.JFrame {
   
    public LabelTest() {
        initComponents();
    }
   
    private void initComponents() {
        thePanel = new javax.swing.JPanel();
        theLabel = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        theLabel.setText("Test");
        thePanel.add(theLabel);

        getContentPane().add(thePanel, java.awt.BorderLayout.CENTER);

        jButton1.setText("jButton1");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jPanel2.add(jButton1);

        getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH);

        pack();
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        theLabel.setText("This is a very long text to test");
    }

    private void exitForm(java.awt.event.WindowEvent evt) {
        System.exit(0);
    }
   
    public static void main(String args[]) {
        LabelTest frame = new LabelTest();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,500);
        frame.setLocationRelativeTo(null);
        frame.show();
    }
   
    // Variables declaration - do not modify
    private javax.swing.JButton jButton1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JLabel theLabel;
    private javax.swing.JPanel thePanel;
    // End of variables declaration
   
}
0
 
StillUnAwareCommented:
//As you can see this JLabel is dinamic

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;

public class C extends JFrame {
  JPanel panel = new JPanel();
  JLabel label = new JLabel("Edit the text below");
  JTextField jtf = new JTextField("Text to change Label text");
  C() {
    label.setBorder(new LineBorder(Color.BLACK));
    panel.setLayout(new FlowLayout());
    panel.add(label);
    jtf.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        String txt = ((JTextField)ae.getSource()).getText();
        label.setText(txt);
        ((JTextField)ae.getSource()).setText("");
      }
    });
    setLayout(new BorderLayout());
    add(panel, BorderLayout.CENTER);
    add(jtf, BorderLayout.SOUTH);
    pack();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
  }
  public static void main(String[] args) {
     C c = new C();
  }
}
0
 
StillUnAwareCommented:
sorry, too late to refresh
0
 
yi02Author Commented:
Dear zzynx:
to your question:
What's the layout of your JPanel?
I used
setLayout(new FlowLayout(FlowLayout.LEFT));
for my JPanel.
I did have JFrame to contain the JPanel, the backbone code is as below:

Public myFrame extends JFrame{
//Constructor
  public myFrame() {  
             
      super("My Frame");  // Call the constructor from the superclass,  
      MyCanvas canvas = new MyCanvas();
       setContentPane(canvas);
       canvas.setVisible(true);
......
     setLocation(0,0);
     setSize(750,600);
      show();
     }
}

Public MyCanvas extends JPanel {
MyCanvas() {
          super();
         setBackground(Color.white);
         addMouseListener(this);
         addMouseMotionListener(this);
         setLayout(new FlowLayout(FlowLayout.LEFT));
......
    }
     
    void AddGeneLabel() {
            //add JLabel to the JPanel      
      MyLabel myLB=new MyLabel("MyLongTextString");
      this.add(myJB);
      repaint();
      //pack(); If I add this line, the whole JPanel shrink to just hold the JPanel ,why is that?how to overcome?
   }
}

Public class MyLabel extends JLabel {

//Constructor accept a text string
 MyLabel(String text){
        super();
       // int lgth=text.length() * 10; if these two lines took out, then JLabel not visible
        // setBounds(1,1,lgth,20); but with pack() it did work, but got another problem, see code please!
        setText("text");
        setForeground(Color.black);
        setOpaque(true);
        setBackground(Color.red);
        setHorizontalAlignment(CENTER);
        setBorder(BorderFactory.createLineBorder(Color.black));
       }
     ...
}


After look at your code, I did try to add the pack() inside the AddGeneLabel() function, but the whole JPanel is shrink to fit the JLabel, how can I overcome this? I try setSize(), which has no effects. But I can manually expand the JPanel when running the program, how can overcome this?

Thanks a lot

yi02
0
 
StillUnAwareCommented:
You may set the myFrame layout to BorderLayout, set it's size to any You like, and add the myCanvas as myFrame.add(canvas, BorderLayout.CENTER); instead of setContentPane(canvas);
0
 
yi02Author Commented:
Dear STillUnAware:

I did what you suggested, it works for the JLabel , but encountered the same problem: The whole JPanel and JFrame shrinked to just hold the JLabel. How can I reset the window size to its original one?

Thanks a lot.

yi02
0
 
objectsCommented:
try:

    void AddGeneLabel() {
            //add JLabel to the JPanel      
      MyLabel myLB=new MyLabel("MyLongTextString");
      this.add(myJB);
      revalidate();
      repaint();
   }
0
 
zzynxSoftware engineerCommented:
>> //pack(); If I add this line, the whole JPanel shrink to just hold the JPanel,
>> why is that?
Well, as the name of the function indicates, it packs ("shrinks", "compresses",...) the frame to its minimal form.
0
 
objectsCommented:
>> //pack(); If I add this line, the whole JPanel shrink to just hold the JPanel,
>> why is that?

from the javadoc:

"Causes this Window to be sized to fit the preferred size and layouts of its subcomponents. If the window and/or its owner are not yet displayable, both are made displayable before calculating the preferred size. The Window will be validated after the preferredSize is calculated."

0
 
yi02Author Commented:
Dear objects:

I did try what you suggested:

revalidate();
      repaint();

it works in that the whole JPanel doe not shrink, but I encounter another problem:

Since in my JPanel, there are other JLabels ( I dynamically add many JLabels to this JPanel and move them arround the JPanel), when I add a new JLabel and did the above codes you suggested, all the other JLabels move together at the top part of JPanel!"

So could you please tell me how to overcome this problem? Thanks a lot.

To accommadate all the efforts of your guys, I increased the points to 400.

thanks,

yi02
0
 
objectsCommented:
> I dynamically add many JLabels to this JPanel and move them arround the JPanel

as your using a layout manager you should not be moving components, that is the job of the layout manager.
If you want to explicitly position components you need to use no layout manager (set layoutmanager to null), and set the size and position of all components when you add them.

> all the other JLabels move together at the top part of JPanel

resizethe panel for example will cause the same to happen
0
 
yi02Author Commented:
Dear objects:

You are right. Even when I resize my panel, which caused the same to happen!

But I do need the capacity to move arround the JLabels within the JPanel!

When I set Layoutmanager to null using "this.setLayout(null);" in JPanel class, when I add JLabel, which now is invisible?!

Any solution that allows me move components but also use layout manager?

Thanks a lot!

yi02
0
 
objectsCommented:
> which now is invisible?!

as well as setting the position, you also need to set the size
0
 
zzynxSoftware engineerCommented:
>> Any solution that allows me move components but also use layout manager?
I'm afraid not.
Or you let the layout manager decide where to place the components (according to its layout)
Or you do it ALL yourself
0
 
yi02Author Commented:
Dear objects and zzynx:

>as well as setting the position, you also need to set the size
that is why I used the layoutmanager, since I need the manager to determine the size of the JLabel based on a given string. So I did not use the size. Do you have a better way that does not use Layoutmanager, but can let the JLabel to fit a given string based on the length of the string? Thanks a lot.

>> Any solution that allows me move components but also use layout manager?
>I'm afraid not.
Do you have a better way that does not use Layoutmanager, but can let the JLabel to fit a given string based on the length of the string? Thanks a lot.

I used to have to calculate the length of string and then determine the width of JLabel before adding it dynamically to the JPanel. Now I am trying to do it with LayoutManager but it appears failed.


y02



0
 
objectsCommented:
You can get the preferred size of the label using:

Dimension size = label.getPreferredSize();

Then use that to size your label.
0
 
yi02Author Commented:
Dear objects:

Your suggestion Dimension size = label.getPreferredSize(); kind of works for the purpose of fit the JLabel to any given string. Thanks a lot!!!

But I did run into a situation as followed:

Since I need turn off the LayoutManager to keep the arrangement of those dynamically added JLabels, I have to turn off the LayoutManager after add the first JLabel dynamically. if I turn off from the beginning from the JFrame, I even could not see my JPanel (only see JFrame, so when I add JLabel to JPanel dynamically, I could not see the added JLabel as well):
(below is the code for JFrame and JPanel)
My question is: Is the LayoutManager  required for JPanel show up on the JFrame? Any solution that not use LayoutManager but still show up the JPanel on top of JFrame?


Public myFrame extends JFrame{
//Constructor
  public myFrame() {  
             
      super("My Frame");  // Call the constructor from the superclass,  
      MyCanvas canvas = new MyCanvas();
       getContentPane().setLayout(new BorderLayout()); //if I eliminate these two lines,
       getContentPane().add(canvas, BorderLayout.CENTER); //I can not even see the JPanel

......
     setLocation(0,0);
     setSize(750,600);
      show();
     }
}

Public MyCanvas extends JPanel {
MyCanvas() {
          super();
         setBackground(Color.white);
         addMouseListener(this);
         addMouseMotionListener(this);
         ......
    }

 void AddJLabel() {
            //add JLabel to the JPanel      
      MyLabel myLB=new MyLabel();
      this.add(myJB);
     
   }
}

Public class MyLabel extends JLabel {

//Constructor accept a text string
 MyLabel(){
          super();
        setBorder(BorderFactory.createLineBorder(Color.black));
        setText("MyLongLongLongString");
        Dimension size = getPreferredSize();
        setBounds(1,1,(int)size.getWidth(),(int)size.getHeight());
        setForeground(Color.black);
        setOpaque(true); //important for setBackground to work  
        setBackground(Color.red);
        setHorizontalAlignment(CENTER);
            addMouseListener(this);
            addMouseMotionListener(this);       }
     ...
}



Notice the two lines of code in class MyFrame:
getContentPane().setLayout(new BorderLayout());
getContentPane().add(canvas, BorderLayout.CENTER);

if I eliminate these two lines, I can not even see the JPanel. Is the LayoutManager  required for JPanel show up on the JFrame? Any solution that not use LayoutManager but still show up the JPanel on top of JFrame?

Thanks again!

Best regards,


yi02





0
 
objectsCommented:
> Is the LayoutManager  required for JPanel show up on the JFrame?

No it is just responsible for sizing and position the components.

>     getContentPane().setLayout(new BorderLayout()); //if I eliminate these two lines,

You only need to remove the layout manager from the panel that you are adding your labels to, you can keep the layout manager for your frame

Public MyCanvas extends JPanel {
MyCanvas() {
         setLayout(null);
         setBackground(Color.white);
         addMouseListener(this);
         addMouseMotionListener(this);
         ......
    }

0
 
yi02Author Commented:
Dear objects:

Thanks a lot. It works. Your solution is the most effective!!!! Greatly appreciated!

Best wishes to you!

yi02
0
 
zzynxSoftware engineerCommented:
Thanks
0
 
objectsCommented:
no worries :)
0

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

  • 7
  • 7
  • 6
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now