JProgressBar Problem

MScalli

Erfahrenes Mitglied
Hi Leutz.
Hab ein kleines Problem mit einer JProgressBar.
Wenn ich ein Seperates Programm mache funktioniert das alles einwandfrei..
Code:
import java.awt.BorderLayout;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;

public class Main {
  public static void main(String[] args) {

    int min = 0;
    int max = 300;
    
    final JDialog dlg = new JDialog();
    JProgressBar dpb = new JProgressBar(min, max);
    dlg.add(BorderLayout.CENTER, dpb);
    dlg.add(BorderLayout.NORTH, new JLabel("Progress..."));
    dlg.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
    dlg.setSize(300, 75);

    Thread t = new Thread(new Runnable() {
      public void run() {
        dlg.setVisible(true);
      }
    });
    t.start();
    for (int i = min; i <= max; i++) {

      dpb.setValue(i);
      
      if(dpb.getValue() == max){
        dlg.setVisible(false);
        System.exit(0);
      }
      try {
        Thread.sleep(25);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    dlg.setVisible(true);
  }
}

So jetzt will ich das gleiche(auch einfach mal mit festen werten) in mein Programm packen.
Die Klasse ist ein JInternalFrame die einen ActionLIstener und einen DocumentListener hat.
Ich will bei nem Button(testweise der 'close' button) das ding starten.
einfach nur mal zum laufen bringen...
Es ist genau das selbe in grün..
Code:
	if(cmd.equals("close")){

		int min = 0;
		int max = 200;

	    final JDialog dlg = new JDialog();
	    JProgressBar dpb = new JProgressBar(min, max);
	    dlg.add(BorderLayout.CENTER, dpb);
	    dlg.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
	    dlg.setSize(300, 75);
	    
	    Thread t = new Thread(new Runnable() {
	        public void run() {
	          dlg.setVisible(true);
	        }
	    });
	    t.start();
	    
	    for (int i = min; i <= max; i++) {
	        dpb.setValue(i);
	        
	        if(dpb.getValue() == max){
	        	dlg.setVisible(false);
	        }
	        try {
	        	Thread.sleep(25);
	        } catch (InterruptedException e) {
	        	e.printStackTrace();
	        }
	    }
	    dlg.setVisible(true);
	    
		//doAtExit();
	}

der JDialog wird erstellt
Mein Problem ist das er den Balken bei setValue nicht zeichnet..
Geschlossen wird er auch zum schluss(ich öffne nur noch mal damit man sieht das der balken zum schluss voll ist)
Woran könnte das denn liegen
Hat wer ne Idee oder nen ander Lösung
 
Zuletzt bearbeitet:
Hallo,

Es wäre meiner Ansicht nach einfacher, wenn du den gesamten Code, also das gesamte Projekt hier als archivierstes File beilegst. So kann man das ganze auch selbst kompilieren und ausprobieren.

MfG Nadriel
 
Das ist leider nicht möglich da es nen riesen ding ist.. masse imports nötig sind da ich viele externe Klassen verwende.. konfig datein und und und..
kann es sein das ich hier irgendwie mit SwingUtilities.invokeLater arbeiten muss
Hab da jetzt paar sachen gelesen!!
 
Hallo.

Hmm, naja wie gesagt wär so einfacher aber wenn es nicht geht muss es auch so zu lösen sein.

Wie zeichnet du eigentlich deine Oberfläche. Hast du dazu ein GUI-Toolkit wie Jigloo in Eclipse, oder wie machst du das?

edit: dieser generiert dir nämlich automatisch im main() folgenden Code (bezüglich deiner Frage wegen invokeLater):
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
asdf inst = new asdf();
frame.getContentPane().add(inst);
((JComponent)frame.getContentPane()).setPreferredSize(inst.getSize());
frame.pack();
frame.setVisible(true);
}
});

MfG Nadriel
 
Zuletzt bearbeitet:
ist des nen LookAndFeel da benutz ich nämlich nimrod
oder wie meinst du die Frage wie ich meine Oberfläche zeichne

So würde es bei mir im Programm laufen... aber eigentlich sollte ja die JProgressBar in nem Thread laufen und nicht mein Programm :(
Mein Hauptprogramm soll in nem Thread ne JProgressBar erstellen und diese auch verändern können..

aufruf auf dem Button 'close'
Code:
	if(cmd.equals("close")){

		final int min = 0;
		final int max = 200;

		pFrame = new MyProgressJFrame(min, max, FerixAuftrag.desktop);

		Thread compareThread = new Thread(new Runnable() {

			public void run() {

				for (int i = min; i <= max ; i++) {

					final int val = i;
					SwingUtilities.invokeLater(new Runnable() {

						public void run() {

							pFrame.updateBar(val);
						}
					});
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});
		compareThread.start();

		//doAtExit();
	}


Code:
package com.hilmer.components;

import java.awt.FlowLayout;
import java.awt.Point;

import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

public class MyProgressJFrame extends JFrame {
	private JPanel pan;
	private JProgressBar bar;

	private int start;
	private int end;
	private JDesktopPane frm;

	public MyProgressJFrame(int start, int end, JDesktopPane frm) {
		super("Progress JFrame");
		this.start = start;
		this.end = end;
		this.frm = frm;
		pan = new JPanel();
		pan.setSize(200, 50);
		pan.setLayout(new FlowLayout());

		bar = new JProgressBar();
		bar.setMinimum(start);
		bar.setMaximum(end);

		pan.add(bar);

		getContentPane().add(pan);

		setSize(200, 50);
		Point loc = frm.getLocation();
		loc.setLocation(
			loc.getX() + 400 + 50,
			loc.getLocation().getY());
		setLocation(loc);
		setVisible(true);

	}
	public void updateBar(int val) {
		bar.setValue(val);
	}
}
 
Hallo.

Also zu deinen ersten Fragen:

Eclipse ist eine Entwicklungsumgebung, wie zB Visual Studio, Dev-Cpp, Borland, etc. und Jigloo ist quasi so etwas wie ein Addon, mit dem du die Oberfläche per Drag & Drop zeichnen kannst. Jigloo generiert dir dann dazu auch den Java-Code.

Also ich denke mal, du schreibst bzw. definierst die Oberfläche per Hand.

Hast du schon mal versucht, das ganze so zu lassen wie es früher war nur jetzt mit dem invokeLater erweitert also:

Code:
import java.awt.BorderLayout;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;

public class Main {
  public static void main(String[] args) {

    int min = 0;
    int max = 300;
    
    final JDialog dlg = new JDialog();
    JProgressBar dpb = new JProgressBar(min, max);
    dlg.add(BorderLayout.CENTER, dpb);
    dlg.add(BorderLayout.NORTH, new JLabel("Progress..."));
    dlg.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
    dlg.setSize(300, 75);

    Thread t = new Thread(new Runnable() {
      public void run() {
        dlg.setVisible(true);
      }
    });
    t.start();
    for (int i = min; i <= max; i++) {
      SwingUtilities.invokeLater(new Runnable() {
        dpb.setValue(i);
      });
      if(dpb.getValue() == max){
        dlg.setVisible(false);
        System.exit(0);
      }
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    dlg.setVisible(true);
  }
}

Und wenn das auch nicht geht, dann steig ich auch leider aus, hörte sich anfangs nach einem einfachem Problem an aber jetzt setz ich langsam doch aus. :-)

MfG
Nadriel
 
Hallo.

Hab nun das ganze mal anhand eines Beispiels von mir entwickelt.

Vielleicht hilft dir das weiter.

Dazu hab ich zwei Klassen:

- thread.java:
Code:
package gui;

import javax.swing.JProgressBar;
import javax.swing.JTextArea;

public class thread implements Runnable{

	private JProgressBar progressBar;
	private JTextArea textArea;
	private int MAX;
	private int MIN;
	
	public thread(JTextArea textArea, JProgressBar progressBar, int MAX, int MIN) {
		this.progressBar = progressBar;
		this.MAX = MAX;
		this.MIN = MIN;
		this.textArea = textArea;
	}
	
	@Override
	public void run() {
		while (progressBar.getValue() < MAX && !(Thread.interrupted())) {
			textArea.setText("Wird geladen ...");
			for (int i = MIN; i <= MAX; i++) {
				try {
					Thread.sleep(25);
				} catch (InterruptedException a) {
					a.printStackTrace();
				}
				progressBar.setValue(i);
			}
		}
		textArea.setText("Geladen!");
	}
}

und Main.java:
Code:
package gui;

import java.awt.BorderLayout;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class Main extends javax.swing.JApplet implements ActionListener {
	private static final long serialVersionUID = 1L;

	private JPanel pMain;
	private JTextArea textArea;
	private JProgressBar progressBar;
	private JButton bStart;

	private thread t1;
	private Thread t2;
	private int MAX = 100;
	private int MIN = 0;

	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				JFrame frame = new JFrame();
				Main inst = new Main();
				frame.getContentPane().add(inst);
				((JComponent) frame.getContentPane()).setPreferredSize(inst
						.getSize());
				frame.pack();
				frame.setVisible(true);
			}
		});

	}

	public Main() {
		super();
		initGUI();
	}

	private void initGUI() {
		try {
			setSize(new Dimension(400, 300));
			
			pMain = new JPanel();
			BorderLayout pMainLayout = new BorderLayout();
			pMain.setLayout(pMainLayout);
			getContentPane().add(pMain);

			bStart = new JButton();
			pMain.add(bStart, BorderLayout.NORTH);
			bStart.setText("Start");

			progressBar = new JProgressBar();
			pMain.add(progressBar, BorderLayout.SOUTH);

			progressBar.setValue(MIN);

			textArea = new JTextArea();
			pMain.add(textArea, BorderLayout.CENTER);
			textArea.setText("Noch nichts gemacht...");

			bStart.addActionListener(this);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		Object o = e.getSource();

		if (o == bStart) {
			t1 = new thread(textArea, progressBar, MAX, MIN);
			t2 = new Thread(t1);
			t2.start();
		}

	}

}

Hoffe das hilft dir.

MfG
Nadriel
 
Habe die obere Variante mal ausprobiert. (paar kleine änderungen musste ich machen) aber leider keinen Erfolg

Hier mal der Code
Code:
	if(cmd.equals("close")){

	    int min = 0;
	    int max = 300;
	    
	    final JDialog dlg = new JDialog();
	    final JProgressBar dpb = new JProgressBar(min, max);
	    dlg.add(BorderLayout.CENTER, dpb);
	    dlg.add(BorderLayout.NORTH, new JLabel("Progress..."));
	    dlg.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
	    dlg.setSize(300, 75);

	    Thread t = new Thread(new Runnable() {
	      public void run() {
	        dlg.setVisible(true);
	      }
	    });
	    t.start();
	    for (int i = min; i <= max; i++) {
	    	
		    final int zaehler = i;
		    SwingUtilities.invokeLater(new Runnable() {
	
				@Override
				public void run() {
					
					dpb.setValue(zaehler);
				}
		    });
		    if(dpb.getValue() == max){
		        dlg.setVisible(false);
		        System.exit(0);
		    }
		    try {
		        Thread.sleep(100);
		    } catch (InterruptedException e) {
		        e.printStackTrace();
		    }
	    }
	    dlg.setVisible(true);

	    
		//doAtExit();
	}

Zu der 2ten Variante muss ich leider sagen das ich es so in der Richtung ja schon habe.
Ich muss aber das Ding so hin bekommen das die ProgressBar in nem Thread erzeugt wird, ich
setValue aber ausserhalb setzte..
In meinem Fall soll nämlich im Hauptprogramm ein ResultSet erzeugt werden
das ich durchlese und bei jedem Satz eine Tabelle fülle.
min = 0 und max = hole ich mit einem SELECT COUNT(0)

jetzt will ich bei jedem Satz die ProgressBar-Value erhöhen

Schon mal fettes merci für deine mühe..
Ich bin echt langsam am verzweifeln den ich kenne dieses Problem schon länger.
Bis jetzt habe ich es immer so gelöst das ich dann die Verarbeitung in nen Thread packe(so wie oben bei mir)
aber die murkserei muss doch mal nen ende haben :(
 
Jetzt habe ich ne Lösung.
Bitte keine bösen kommentare.. EIne andere Lösung hab ich einfach net :(
Über Vorschläge wie ich es besser machen kann bin ich natürlich sehr dankbar..
Code:
	if(cmd.equals("close")){

	    int min = 0;
	    int max = 300;
	    
	    final JDialog dlg = new JDialog();
	    JProgressBar dpb = new JProgressBar(min, max);
	    dpb.setStringPainted(true);
	    dlg.add(BorderLayout.CENTER, dpb);
	    dlg.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
	    dlg.setSize(300, 75);

	    Thread t = new Thread(new Runnable() {
	      public void run() {
	        dlg.setVisible(true);
	      }
	    });
	    t.start();
	    for (int i = min; i <= max; i++) {

	      dpb.setValue(i);
	      dpb.paint(dpb.getGraphics()); // <- so das Zeichnen erzwingen
	      
	      if(dpb.getValue() == max){
	        dlg.setVisible(false);
	        System.exit(0);
	      }
	      try {
	        Thread.sleep(100);
	      } catch (InterruptedException e) {
	        e.printStackTrace();
	      }
	    }
	    dlg.setVisible(true);

	    
		//doAtExit();
	}

und nochmal vielen dank an Nadriel
 
Hallo.

Hast du schon versucht eine eigene Thread-Klasse zu Erzeugen, wo du mit dem Konstruktor den du in deinem Hauptprogramm aufrufst, alles übergibst was du brauchst, wie bereits oben:

Erst erzeugst du die wie bereits besagte Klasse thread.java:
Code:
package gui;

import javax.swing.JProgressBar;
import javax.swing.JTextArea;

public class thread implements Runnable{

	private JProgressBar progressBar;
	private JTextArea textArea;
	private int MAX;
	private int MIN;
	
	public thread(JTextArea textArea, JProgressBar progressBar, int MAX, int MIN) {  // Hier die Elemente die du brauchst, Textfelder oder derartiges
		this.progressBar = progressBar;
		this.MAX = MAX;
		this.MIN = MIN;
		this.textArea = textArea;
	}
	
	@Override
	public void run() { //Hier erhöhst du dann immer den Value von der progressBar um 1
		while (progressBar.getValue() < MAX && !(Thread.interrupted())) {
			textArea.setText("Wird geladen ...");
			for (int i = MIN; i <= MAX; i++) {
				try {
					Thread.sleep(25);
				} catch (InterruptedException a) {
					a.printStackTrace();
				}
				progressBar.setValue(i);
			}
		}
		textArea.setText("Geladen!");
	}
}

Danach im Hauptprogramm erzeugst du 2 Objekte:
Code:
private thread t1;
private Thread t2;

Und der nächste Schritt dann noch im Hauptprogramm, in der actionperformed das hier:
Code:
t1 = new thread(textArea, progressBar, MAX, MIN);
t2 = new Thread(t1);
t2.start();
edit: klar ist, dass du das dort schreibst wo ActionEvent.getSource() = deinem Button

Normalerweise dürfte es doch so funktionieren probiere es mal mit einer eigenen Klasse. Wenns nicht geht bleib bei deiner Variante, Hauptsache ist, dass es funktioniert :D

Grüße
Nadriel
 
Zuletzt bearbeitet:
Zurück