简体   繁体   English

JFrame / JPanel不更新重新绘制或重新验证

[英]JFrame/JPanel does not update repaint or revalidate

Im trying to update my panel once each second but i don't get it to work. 我试图每秒更新一次我的面板,但我无法正常工作。 i tried almost everything even using revalidate and repaint but it still doesn't work. 我什至尝试使用revalidate和repaint进行几乎所有操作,但仍然无法正常工作。 What am i doing wrong? 我究竟做错了什么?

The code for refreshing each second and getting te time does work perfectly but i only cant get it to work with the GUI. 每秒刷新并获取时间的代码确实可以很好地工作,但是我只能使其与GUI一起使用。 It only appears once and after that i wont update anymore. 它只出现一次,之后我将不再更新。 This is how it looks like 看起来像这样

Here is my JFrame code.. 这是我的JFrame代码。

public class MainFrame extends JFrame{
WeatherWidget weatherWidget = new WeatherWidget();
DateTimeWidget dateTimeWidget = new DateTimeWidget();

Timer weatherRefreshTimer = new Timer(1000*60, new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == weatherRefreshTimer){
           // weatherWidget.retreatWeatherInformation();
            weatherWidget.updateWeatherUI();
            repaint();
            System.out.println("Updated weather");
        }
    }
});


Timer dateTimeRrefreshTimer = new Timer(1000, new ActionListener() {

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == dateTimeRrefreshTimer){

            dateTimeWidget.retreatDateTimeInformation();
            dateTimeWidget.updateDateTimeUI();

            repaint();
            System.out.println("Updated Time and Date");
        }
    }
});

public MainFrame(){
    this.setSize(540, 950);
    this.getContentPane().setBackground(new Color(0,0,0));
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.getContentPane().setLayout(null);
    this.setResizable(false);

    addWeatherComponents();
    addDateTimeComponents();

    this.setVisible(true);

    weatherRefreshTimer.start();
    dateTimeRrefreshTimer.start();
}

public void addWeatherComponents(){
    this.add(weatherWidget.getWeerIconLabel());
    this.add(weatherWidget.getTemperatureLabel());
    this.add(weatherWidget.getPlaatsLabel());
}

public void addDateTimeComponents(){
    this.add(dateTimeWidget.getTimeLabel());
}

public void repaint(){
    this.getContentPane().revalidate();
    this.getContentPane().repaint();
}


}

And this is where i have my JLabels 这是我拥有我的JLabels的地方

public class DateTimeWidget {
private String time;
private String date;

private int hour;
private int minutes;
private int seconds;
private int day;
private int month;
private int year;

private JLabel timeLabel;
private JLabel dateLabel;

public DateTimeWidget(){
    retreatDateTimeInformation();
    updateDateTimeUI();
}

public void updateDateTimeUI(){
    timeLabel = new JLabel();
    timeLabel.setText(time);
    timeLabel.setBounds(350, 10, 200, 30);
    timeLabel.setForeground(new Color(255,255,255));
    timeLabel.setHorizontalAlignment(SwingConstants.LEFT);
    timeLabel.setBackground(new Color(Transparency.TRANSLUCENT));
    timeLabel.setFont(new Font("Tahoma", Font.BOLD, 30));
    timeLabel.setOpaque(false);

}

public void retreatDateTimeInformation(){
    LocalDateTime now = LocalDateTime.now();
    hour = now.getHour();
    minutes = now.getMinute();
    seconds = now.getSecond();
    day = now.getDayOfMonth();
    month = now.getMonthValue();
    year = now.getYear();

    time =    Integer.toString(hour)+":"+Integer.toString(minutes)+":"+Integer.toString(seconds);

    System.out.println(time);

}

public JLabel getTimeLabel() {
    return timeLabel;
}
}
public void updateDateTimeUI(){
    timeLabel = new JLabel();
    timeLabel.setText(time);
    timeLabel.setBounds(350, 10, 200, 30);
    timeLabel.setForeground(new Color(255,255,255));
    timeLabel.setHorizontalAlignment(SwingConstants.LEFT);
    timeLabel.setBackground(new Color(Transparency.TRANSLUCENT));
    timeLabel.setFont(new Font("Tahoma", Font.BOLD, 30));
    timeLabel.setOpaque(false);

}

Don't keep creating new components!!! 不要继续创建新组件!!!

The label should be created once and added to the frame once. 标签应创建一次并添加到框架一次。

Then when the Timer fires to change the data you simply invoke: 然后,当计时器触发以更改数据时,您只需调用:

timeLabel.setText(....);

in the ActionListener code (after you determine the new date/time). (在确定新的日期/时间之后)在ActionListener代码中。

Also, there is no need for the if statement in the Timer ActionListener. 另外,在Timer ActionListener中不需要if语句。 The listener is only added to one Timer so the code will only be executed when the Timer fires. 侦听器仅添加到一个Timer,因此仅在Timer触发时才执行代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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