Swing Fenster jede sec.neuzeichnen

  • Themenstarter Themenstarter KlemensyXYZ
  • Beginndatum Beginndatum
K

KlemensyXYZ

Gast
Hallo,

ich möchte ein Swing Fenster jede Sekunde neuzeichnen.
Das ganze soll eine Uhr werden.
Java:
package ticktack;

import java.util.Date;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Uhr.java
 *
 * Created on 12.04.2011, 08:21:22
 */

/**
 *
 * @author Klemens
 */
@SuppressWarnings("serial")
public class Uhr extends javax.swing.JFrame {

    /** Creates new form Uhr */
    public Uhr() {
    	
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
        jLabel1.setText("Uhr");

        jLabel2.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jLabel2.setText(String.format("%tT" , new Date ()));
        jLabel2.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 1, true));

        jButton1.setText("Beenden");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jButton1)))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(33, 33, 33)
                        .addComponent(jLabel1)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addGap(11, 11, 11)
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jButton1)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Uhr().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    // End of variables declaration

}

nur weis ich nicht wie ich das machen soll.
ich dachte da an repaint() aber ich habe da noch nichts gefunden was funktionierte.
Wo in meinem Quelltext muss ich denn das überhaupt unterbringen?

Danke
 
1) In nen Thread oder TimerTask jede Sekunde repaint aufrufen.
2) Eine schlechte Idee, es sollte immer nur der veränderte Bereich wenn möglich gezeichnet werden. Afaik sind repaints das langsamste und gleichzeitig zeitkritischte überhaupt. (Wenn man mal von irgend welchen riesen Algo's absieht.)
3) Swing zeichnet bei "positiven" (so nenne ich das eben) Änderungen, wie setVisible(true), setText(String s), add(Container c) automatisch neu, nur bei "negativen" setVisible(false), remove(Container c) nicht. Du müsstest also einfach nur die neue Uhrzeit mit setText setzen.
 
Hier mal noch nen kleines Beispiel mit nem swing Timer:

Java:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main {
	public static void main(String[] args) {
		JFrame frame = new JFrame("Counter test");
		frame.setLayout(new FlowLayout());
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		frame.add(new Counter());
		frame.pack();
		frame.setVisible(true);
	}
	
	static class Counter extends JPanel {

		private int counter = 0;
		private Timer timer = null;
		
		public Counter() {
			setPreferredSize(new Dimension(100,100));
			
			timer = new Timer(1000, new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					counter++;
					repaint();
				}
			});
			timer.setRepeats(true);
			timer.start();
		}
		
		@Override
		protected void paintComponent(Graphics g) {
			super.paintComponent(g);
			g.drawString("Counter: " + counter, 20, 20);
		}
	}
}
 
ich bekomms nicht hin
hab mir jetzt ne neue Klasse geschrieben:

Java:
package ticktack;

import java.util.Timer;
import java.util.TimerTask;

public class UhrTimer
{
	private int count = 0;
	    
	    public UhrTimer() 
	    {
	        Timer timer = new Timer();
	        TimerTask task = new TimerTask() 
	        {
	            @Override
	            public void run() 
	            {
	                System.out.println(count);
	                if (count > 0)
	                {
	                	count++;
	                	Uhr.repaint();
	                }
	                    
	                
	                if (count == 0)
	                {
	                	count++;
	                	new Uhr().setVisible(true);
	                }
	            }
	        };
	        timer.schedule(task, 0, 1000);
	    }
	    
	    public static void main(String[] args) 
	    {
	        new UhrTimer();
	    }
	}

geht trotzdem nicht, das repaint ist rot unterstrichen
 
Hm, weil ich so ein netter Kerl bin.

Das verwende ich in einen Projekt. Ist zwar nicht das Schönste, ich hab mich hinterher gefragt, warum ich nicht einfach jede Sekunde die neue Uhrzeit auslese. Habs aber nicht übers Herz gebracht, den Task wieder so zu minimieren. 😳

Java:
package at.kai.taskbar.systemTrayArea;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JLabel;
import javax.swing.SwingUtilities;

class TimeLabel extends JLabel
{
	private static final long serialVersionUID = 1L;

	TimeLabel()
	{
		super();
		
		TimerTask ic = new IncreaseClock();
		Timer t = new Timer();
		t.scheduleAtFixedRate(ic, 1000, 1000);
	}
	private class IncreaseClock extends TimerTask
	{
		private int hour;
		private int minutes;
		private int seconds;
		
		private IncreaseClock()
		{
			super();
			hour = Integer.parseInt(getTime("H"));
			minutes = Integer.parseInt(getTime("m"));
			seconds = Integer.parseInt(getTime("s"));
			
			setTime();
		}
		public void run()
		{
			boolean setTime = false;
			
			seconds++;
			if(seconds == 60)
			{
				minutes++;
				seconds = 0;
				setTime = true;	
			}
			if(minutes == 60)
			{
				hour++;
				minutes = 0;
				setTime = true;
			}
			if(hour == 24)
			{
				hour = 0;
				minutes = 0;
				seconds = 0;
				setTime = true;
			}
			
			if(setTime)
			{
				SwingUtilities.invokeLater(new Runnable() {
					public void run()
					{
						setTime();
					}
				});	
			}
		}
		private String getTime(String string)
		{
			SimpleDateFormat sdf = new SimpleDateFormat(string);
			return(sdf.format(new Date()));
		}
		private void setTime()
		{
			String h = String.valueOf(hour);
			if(h.length() == 1)
				h = "0" + h;
			
			String m = String.valueOf(minutes);
			if(m.length() == 1)
				m = "0" + m;
			
			setText(h + ":" + m);
		}
	}
}
 
ok, da steig ich gar nicht durch

andere Frage/Möglichkeit:
ich meine gelesen zu haben das das auch mit repaint(1000) gehen soll.
Wo in meinem Quelltext für das Fenster müsste ich denn das unterbringen?

und zeichnet das das Fenster dann nur einamal neu oder dauerhaft?
 
nein es gibt keine repaint(1000); Methode (außer man überläd die vorhandene repaint methode von swing..).
Aber die müsste man dann auch selbst implementieren.

Meine Klasse Counter oben macht doch im Prinzip genau das was du willst. Es ist nen JPanel dass sich jede Sekunde neuzeichnet. Im Actionlistener kannst du dann machen was du willst, z.b. die aktuelle Uhrzeit auslesen.

EDIT:
scheinbar gibts doch so ne Methode 😉
 
Zuletzt bearbeitet von einem Moderator:
Das wird nicht funktionieren.
Code:
[B]tm[/B] maximum time in milliseconds before update

Meins brauchst du nur in eine Klasse im Projekt kopieren (package muss natürlich geändert werden), und ganz normal als JLabel verwenden.
Eike hat sogar ein ganzes Programm gepostet.
 
Das wird nicht funktionieren.
Code:
[B]tm[/B] maximum time in milliseconds before update

Meins brauchst du nur in eine Klasse im Projekt kopieren (package muss natürlich geändert werden), und ganz normal als JLabel verwenden.
Eike hat sogar ein ganzes Programm gepostet.

mein problem ist das ich das mit den mir bekannten Mitteln realisieren muss.
D.h. an dem von mir als erstes geposteten Quelltext.
Dieser ist durch NetBeans auto generiert; ich habe nur
Code:
jLabel2.setText(String.format("%tT" , new Date ()));
ergänzt.

Meine Frage ist nach wie vor wie ich dieses Fenster mit einer Zeitangabe einmal die sec. aktualisieren kann, sodass dort immer die Aktuelle Systemzeit steht.

Das heißt auch das ich von niemandem die schönen Programme kopieren kann oder auch will.
ich würde nur gerne wissen wo und wie ich die Methode repaint(), bzw. repaint(1000) in meinem
Quelltext unterbringen kann/soll.

Trotzdem erstmal danke für eure Bemühungen.
 
Jetzt ist es ein dir bekanntes Mittel. 😉
Du versuchst das Fenster neu zu zeichnen, was aber doch garnichts mit der Aufgabenstellung zu tun hat. Du musst einfach nur die neue Uhrzeit setzen. Dann zeichnet er sowieso selbstständig neu.
 
ich glaube ich habs kapiert

ein timer der einmal die sec. das jLabel neu "befüllt"?

mal testen

edit:

:applaus:FUNKTIONIERT:applaus:
 
Zuletzt bearbeitet von einem Moderator:
@TO
FAIL

bereits im zweiten post schreibt volvagia das bei z.b. eben setText() automatisch neu gezeichnet wird ...

wenn du dir DAS zu herzen genommen hättest hättest du gewusst das dieser schwachsinn mit "das fenster komplett neu zeichnen" überflüssig ist ... den ein einfaches JLabel.setText() reicht aus um es auch sichtbar zu ändern ... proiers mal mit nem ganz simplen ding aus

Java:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class JLabelRepaintTest extends Thread
{
   JLabel jLabel;
   int c=0;
   public static void main(String[] args) throws Exception { (new JLabelRepaintTest()).start); }
   public JLabelRepaintTest throws Exception
   {
      jLabel=new JLabel(c);
      JFrame jf=new JFrame("TEST");
      jf.setLocation(200, 100);
      jf.add(jLabel);
      jf.pack();
      jf.setVisible(true);
   }
   public void run()
   {
      try
      {
         while(true)
         {
            jLabel.setText(c);
            c++;
            this.sleep(1000);
         }
      } catch(Exception e) { }
   }
}
 

Neue Themen


Zurück
Oben