0

I have my GUI:

JTextPane numbers;

JFrame frame = new JFrame("GUI");
Numbers nums = new Nums();
numbers = new JTextPane();
frame.setLayout(new GridLayout(0,3));
JPanel p = new JPanel(new GridLayout(0,1));
frame.add(p);
p.add(new JLabel("Phone numbers: "));
numbers.add(nums);
p.add(numbers);
frame.pack();
frame.setVisible(true);

Numbers class:

public class Numbers extends JLabel implements Timing {

private TimerCallback nos;

public Numbers(){
    setPreferredSize(new Dimension(500, 250));
    nos = new TimerCallback(this, 100L);
    nos.start();
}   

@Override
public void tick() {
    repaint();
}

@Override
public void paintComponent(Graphics g){
    String pn = phoneNumbersMap.toString();
    g.drawString("Phone numbers: \n"+pn, 75, 10);
}

}

The problem is that GUI does not display info from paintComponent in numbers TextPane. What can I do to display text there?

Alex B.
  • 47
  • 7

1 Answers1

0

While overriding paintComponent() is possible, you should avoid it where possible. Swing is doing a pretty good job when you are using the provided Components as is.

In your case, I would suggest deriving Numbers from JTextPane instead of JLabel. Now, do your phoneNumbersMap to String magic there and set it via JTextPane.setText().

I suppose your TimerCallback is somehow running on a Thread different from EDT. In this case, wrap the setText() call in SwingUtilities.invokeLater() to make sure Swing can repaint it properly.

By the way, you have chosen to use two cascaded GridLayouts. Unless this is not caused by you, trying to reduce the example, you might want to take a look at the BorderLayout, which I used in GUI below.

I changed your example a bit to be able to execute it and get some output. Here my code proposal.

GUI:

JFrame frame = new JFrame("GUI");
Numbers numbers = new Numbers();
frame.setLayout(new BorderLayout());
frame.add(new JLabel("Phone numbers: "), BorderLayout.NORTH);
frame.add(numbers,BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);

Number:

public class Numbers extends JTextPane implements Timing {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private String phoneNumbersMap = "Start";

    private TimerCallback nos;

    public Numbers() {
        setPreferredSize(new Dimension(500, 250));
        nos = new TimerCallback(this, 100L);
        nos.start();
    }

    @Override
    public void tick() {
        phoneNumbersMap += "Test\n";
        String pn = phoneNumbersMap.toString();
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                Numbers.this.setText("Phone numbers: \n" + pn);
            }
        });
    }

}

Timing Interface:

public interface Timing {

    void tick();

}

TimerCallback:

public class TimerCallback {

    Timer tim;
    private long period;
    private Numbers numbers;

    public TimerCallback(Numbers numbers, long period) {
        tim = new Timer(true);
        this.period = period;
        this.numbers = numbers;
    }

    public void start() {
        tim.scheduleAtFixedRate(new TimerTask() {

            @Override
            public void run() {
                TimerCallback.this.numbers.tick();
            }
        }, new Date(), period);
    }

}
Community
  • 1
  • 1
Alexander
  • 1,356
  • 9
  • 16