简体   繁体   中英

Setting text of a JLabel in a 'for' loop

I do have a problem setting text of a JLabel from a for loop. The loopMessage() method just setting the first index of the list, but when I print out I can see all indexes:

meep spring
meep2 winter

I want the label olso setting the whole list on the window

public class ControllerMessage {
    private ModelMessage mm;
    private ViewMessage vm;

    public ControllerMessage(ModelMessage mm, ViewMessage vm) {
        this.mm = mm;
        this.vm = vm;
        loopMessage();
        addMessage();
        loopMessage();
    }

    public void loopMessage() {
        for (Message s : mm.getAllMessages()) {
            System.out.println(s.getName() + " " + s.getDate());
            vm.setLabel(s.getName() + " " + s.getDate());   
        }
    }

    public Message addMessage() {
        return this.mm.addMessage(new Message(2, "meep2", "winter"));
    }
}

the view class:

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ViewMessage extends JFrame{

private JLabel additionLabel = new JLabel();

public ViewMessage() {

    JPanel calcPanel = new JPanel();

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setSize(600, 600);


    calcPanel.add(additionLabel);

    this.add(calcPanel);
 }

 public void setLabel(String m){
    additionLabel.setText(m);
}
}

A JLabel can only hold a String, usually a single line of text. If you want to display text in a loop, but show it for a defined period of time, and then show the next text -- use a Swing Timer. This will save you from having to explicitly create a background thread requiring you to take care that all Swing code calls in the background thread be queued onto the event thread, since the Timer's ActionListener code is guaranteed to be called on the Swing event thread.

If you want to show multiple lines of text, use a JTextArea or a JList. My guess is that you really want to use a JList.

eg,

// better to extend JPanel than JFrame, since this makes your code more flexible.
public class ViewMessage extends JPanel {
   private static final int LIST_WIDTH = 40;
   private static final int VISIBLE_ROWS = 20;
   private DefaultListModel<String> listModel = new DefaultListModel<>();
   private JList<String> messageList = new JList<>(listModel);
   private JLabel additionLabel = new JLabel();

   public ViewMessage() {
      // set the width of the JList
      String listWidth = String.valueOf(LIST_WIDTH);
      String prototypeValue = String.format("%" + listWidth + "s", " ");
      messageList.setPrototypeCellValue(prototypeValue);

      // set the number of JList rows visible in the scrollpane 
      messageList.setVisibleRowCount(VISIBLE_ROWS);

      setLayout(new BorderLayout());
      add(new JScrollPane(messageList));
   }

   public void appendMessage(String message) {
      listModel.addElement(message);
   }

}

Since there is no delay, the JLabel is being changed with all the messages, but it is so fast that it is not visible. To fix this, create a thread and make the thread sleep with Thread.sleep(time) .


If you want to print the entire list of messages do this for changing the JLabel: label.setText(label.getText() + " " + messageYouWantToAdd);

I do not know what you view message class is so make that code where ever you are adding text to your label.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM