JLabel在GUI中重叠文本

时间:2015-06-23 14:31:53

标签: java

我正在尝试使用尽可能少的资源创建一个时钟,并且只依赖于我(有限的)Java知识。然而,我来到了路障。我写的时钟工作,除了被替换的jlabel中的文本,它重叠自己。我试过通过清除timeStamp的值来解决这个问题,但它似乎没有用。

public class Clock extends JFrame{
public static void main (String args[]) {       

    Clock gui = new Clock();
    gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    gui.setSize(50,50);
    gui.setVisible(true);
    gui.setTitle("Clock");

    int a = 1;
    while (a == 1){         
        String timeStamp = new SimpleDateFormat("hh:mm:ss a").format(Calendar.getInstance().getTime());         
        JLabel label;
        label = new JLabel();
        label.setText(String.valueOf(timeStamp));
        timeStamp = "";
        gui.add(label);
        label.revalidate();
    }
           }
}

4 个答案:

答案 0 :(得分:1)

每次迭代都不应该创建新的JLabel。

JLabel label = new JLabel();
gui.add(label);
while (a == 1){         
    String timeStamp = new SimpleDateFormat("hh:mm:ss a").format(Calendar.getInstance().getTime()); 
    label.setText(String.valueOf(timeStamp));
    timeStamp = "";
    label.revalidate();
}

答案 1 :(得分:0)

您应该使用SwingWorker来更新时钟。目前,您正在事件调度线程上执行此操作,从而干扰UI呈现。

除此之外,您应该重复使用标签,而不是为每个时间戳创建一个新标签。目前,您正在将标签堆叠在一起,因为{{1}}只会添加新标签,而不会删除旧标签。

答案 2 :(得分:0)

为什么要在循环的每次迭代中创建一个新的JLabel? 不要那样做。 只需在Clock的构造函数中创建一个标签。

此外,更改标签的文本应该在事件线程上完成,而不是主线程。

答案 3 :(得分:0)

虽然您编写的代码"工作",但您缺少一些东西来制作稳定的Swing GUI。

  1. 您必须始终使用SwingUtilities invokelater方法启动Swing应用程序。这将Swing组件的创建和执行放在Event Dispatch thread (EDT)

  2. 我将GUI的创建与GUI的执行分开。关注点分离使每个部分的编码更容易。

  3. 在Timer Runnable中,我再次使用SwingUtilities invokeLater方法确保在EDT上更新带有时间的JTextField。

  4. 我退出前停止线程。通常,您应该停止任何启动的线程,而不是依靠JVM来为您清理。

  5. 这是时钟。

    Simple Clock GUI

    这是代码。

    package com.ggl.testing;
    
    import java.awt.Color;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    
    import javax.swing.BorderFactory;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;
    
    public class SimpleClock implements Runnable {
    
        private JFrame frame;
    
        private JPanel panel;
    
        private JTextField clockDisplay;
    
        private Timer timer;
    
        @Override
        public void run() {
            frame = new JFrame("Clock");
            frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent event) {
                    exitProcedure();
                }
            });
    
            panel = new JPanel();
            panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 6));
    
            clockDisplay = new JTextField(12);
            clockDisplay.setEditable(false);
            clockDisplay.setHorizontalAlignment(JTextField.CENTER);
    
            panel.add(clockDisplay);
    
            frame.add(panel);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
    
            timer = new Timer(this);
            new Thread(timer).start();
        }
    
        public void exitProcedure() {
            timer.setRunning(false);
            frame.dispose();
            System.exit(0);
        }
    
        public void setText(String text) {
            clockDisplay.setText(text);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Clock());
        }
    
        public class Timer implements Runnable {
    
            private volatile boolean running;
    
            private SimpleClock clock;
    
            private SimpleDateFormat timeFormat;
    
            public Timer(SimpleClock clock) {
                this.clock = clock;
                this.running = true;
                this.timeFormat = new SimpleDateFormat("h:mm:ss a");
            }
    
            @Override
            public void run() {
                while (running) {
                    displayTime();
                    sleep();
                }
    
            }
    
            public void displayTime() {
                final Calendar calendar = Calendar.getInstance();
                Date date = calendar.getTime();
                final String s = timeFormat.format(date);
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        clock.setText(s);
                    }
                });
            }
    
            public void sleep() {
                try {
                    Thread.sleep(200L);
                } catch (InterruptedException e) {
                }
            }
    
            public synchronized void setRunning(boolean running) {
                this.running = running;
            }
    
        }
    
    }