-1

I am trying to make a fix-width label in Java, which I find a solution here. But I fail whenever I put any inside a label -- while the label is create inside a method.

my code is here :

public class testingGui

    JFrame myframe      = new JFrame("Some title here");
    Container pane_ctn  = myframe.getContentPane();

    public static void main(String[] args){
        testingGui gui = new testingGui();
        gui.init();
    }

    private void init(){

        myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myframe.setSize(320, 480);
        myframe.setVisible(true);
        pane_ctn.setLayout(new BoxLayout(pane_ctn, BoxLayout.PAGE_AXIS));

        JLabel lable = new JLabel("<html>Java is a general-purpose computer programming language</html>");  
        pane_ctn.add(lable);

    }

}

The line JLabel lable = new JLabel("<html>Java is a general-purpose computer programming language</html>"); will never run. (and making pane_ctn into blank even if there's other UI element added)

However I found that it works while the label is create as a field, like this :

public class testingGui {

    JFrame myframe      = new JFrame("Some title here");
    Container pane_ctn  = myframe.getContentPane();
    JLabel lable = new JLabel("<html>Java is a general-purpose computer programming language</html>");  

    // I just cut the whole line and paste here, nothing else has changed.
    /* ...  */
}

So here is my question : How is the correct way to create a label with html inside a method call ? I need it created on the fly. Thank you.


Edit :

Thank you ybanen giving me a good answer, and others helpers, too.

Now I can creating Label that looking good.

Community
  • 1
  • 1
Theo Ymca
  • 109
  • 2
  • 10

2 Answers2

1

It happens because you try to modify the GUI after it has been displayed. In your case, the best is to create the whole GUI and then to show the frame:

public class TestingGui {

    public static void main(final String[] args) {
        final JLabel label = new JLabel("<html>Java is a general-purpose computer programming language</html>");

        final JFrame frame = new JFrame("Test");
        final Container contentPane = frame.getContentPane();
        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.PAGE_AXIS));
        frame.getContentPane().add(label);
        frame.setSize(320, 480);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

However, if you really need to add the label after the GUI has been displayed, you have to follow several rules:

  1. Any modification of the GUI must be done in the Event Dispatching Thread (EDT).
  2. After a container has been displayed, it has been laid out. So if you want to add a new component inside, you have to force a layout of its content (using revalidate() and then repaint()).
osechet
  • 426
  • 3
  • 11
  • I'll assemble putting `frame.setVisible(true);` into a method, then call it in the end of code, is that good ? Because I hate to put everything into main() – Theo Ymca Feb 20 '15 at 09:36
  • Btw, why is a create a label without '' will not case that display error ? – Theo Ymca Feb 20 '15 at 09:39
  • In this case, I would suggest to create 2 methods: `createGUI()` and `showGUI()`. The first one create the frame and returns it. The second one shows the frame. – osechet Feb 20 '15 at 09:42
  • I'm a little bit surprised by the remark about 'html'. Running my example with the creation of the label after the `setVisible()` gives exactly the same result with or without an 'html' in the string. – osechet Feb 20 '15 at 09:49
  • Wow , thanks !!! It solve my another problem --- setSize() is not working.. P.S. I had notice lots example put `frame.setVisible(true);` in the end of code, And the reason I put it in front is "So that I can debug in the middle of the execution" – Theo Ymca Feb 20 '15 at 09:57
1

I need it created on the fly.

Why? Or rather, why not create and add the label at start-up, then set the text when needed?

My example is a To-Do list, I have a array to store the data, the label is create inside a for loop.

Use a JList!

enter image description here

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class EditableList {

    private JComponent ui = null;

    String[] items = {
        "Do 100 push ups.",
        "Buy a book.",
        "Find a cat.",
        "Java is a general purpose computer language that is concurrent, "
            + "class based, object oriented and specifically designed to have "
            + "as few implementation dependencies as possible.",
        "Conquer the world."
    };

    EditableList() {
        initUI();
    }

    public void initUI() {
        if (ui != null) {
            return;
        }

        ui = new JPanel(new BorderLayout(4, 4));
        ui.setBorder(new EmptyBorder(4, 4, 4, 4));

        JList<String> list = new JList<String>(items);
        list.setCellRenderer(new ToDoListRenderer());
        list.getSelectionModel().setSelectionMode(
                ListSelectionModel.SINGLE_SELECTION);
        ui.add(new JScrollPane(list));

        JPanel controls = new JPanel(new FlowLayout(FlowLayout.CENTER));
        controls.add(new JButton("Edit Selected"));
        controls.add(new JButton("Delete Selected"));

        ui.add(controls, BorderLayout.PAGE_END);
    }

    class ToDoListRenderer extends DefaultListCellRenderer {

        @Override
        public Component getListCellRendererComponent(
                JList<? extends Object> list, 
                Object value, 
                int index, 
                boolean isSelected, 
                boolean cellHasFocus) {
            Component c = super.getListCellRendererComponent(
                    list, value, index, isSelected, cellHasFocus);
            JLabel l = (JLabel)c;
            l.setText("<HTML><body style='width: 250px;'>" + value.toString());

            return l;
        }

    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(
                            UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                EditableList o = new EditableList();

                JFrame f = new JFrame("To Do List");
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • sorry. I don't think "Edit Selected" is a good idea, It look very old fashion. btw, did you saw my image ? – Theo Ymca Feb 20 '15 at 14:41
  • as i said, i am going to make a to-do list, I need to put more things on top of it, E.G. change a row (a item's) background color. – Theo Ymca Feb 20 '15 at 15:58