Threadproblem JTabbedPane

Status
Nicht offen für weitere Antworten.
M

masterbeef

Gast
Habe eine Klasse die eine JTabbedPane beinhaltet, welche JComponents aufnehmen können soll.
Die JComponents stammen aus unterschiedlichen Threads und repräsentieren diesen.
Ich habe 3 Funktionen. Das loader-objekt ist eine JTabbedPane.
Die Jtabbedpane wird ausgeblendet wenn keine Jcomponents auf ihr liegen.

Folgende Funktionen hat diese Klasse:

Code:
...
        private void setLoaderVisible()
	{
		if (loader.getTabCount() == 0)
		{
			loader.setVisible(false);
		} else
		{
			loader.setVisible(true);
		}
	}

	public void removeLoaderComponent(final JComponent component)
	{
		SwingUtilities.invokeLater(new Runnable()
		{

			public void run()
			{
				loader.remove(component);
				setLoaderVisible();
			}
		});
	}

	public void setLoaderComponent(final JComponent component)
	{
		SwingUtilities.invokeLater(new Runnable()
		{

			public void run()
			{
				loader.addTab("Thread " + (loader.getTabCount() + 1), component);
				loader.setSelectedComponent(component);
				setLoaderVisible();
			}
		});
	}
...

Manchmal kommen solche Fehlermeldungen ganz sporadisch:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at java.awt.Container.createHierarchyEvents(Container.java:1335)
at java.awt.Component.show(Component.java:1268)
at java.awt.Component.show(Component.java:1300)
at java.awt.Component.setVisible(Component.java:1253)
at javax.swing.JComponent.setVisible(JComponent.java:2535)
at javax.swing.plaf.basic.BasicTabbedPaneUI.setVisibleComponent(BasicTabbedPaneUI.java:1401)
at javax.swing.plaf.basic.BasicTabbedPaneUI$TabbedPaneScrollLayout.layoutContainer(BasicTabbedPaneUI.java:2621)

Weiß jemand was ich da falsch mache?
 
G

Guest

Gast
ich führe in extra threads berechnungen aus, die sehr lange dauern jetzt möchte ich diese berechnungen mit jprogressbars anzeigen diese jprogressbars werden eben mit setLoaderComponent() und removeLoaderComponent()
hinzugefügt und falls fertig wieder entfernt.

So hat man dann während des programmlaufs eine JTabbedpane im Vordergrund mit mehreren Tabs die alle Thread 1, Thread 2 etc. heißen und ab und dann wieder von der JTabbedPane entfernt werden.
 
G

Guest

Gast
genau genommen werden die in einem SwingWorker thread erstellt und dort mittels setLoaderComponent() und removeLoaderComponent() benutzt.
Das sollte doch gehen, oder?
 

Wildcard

Top Contributor
Das hängt davon ab. Im SwingWorker treffen sich mehrere Threads, die Frage ist also wie die Implementierung aussieht.
Warum erstellst du die Komponenten nicht einfach bevor der SwingWorker läuft?
 
G

Guest

Gast
Hier mal vereinfacht...
Die Art wie ich Swingworker benutze ist doch korrekt, oder?
Code:
public class Main
{
	public static void main(String[] args)
	{
		Window window = new Window();
		LoadingScreen.setWindow(window);
	}
}
Code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JTabbedPane;

public class Window extends JFrame implements ActionListener
{

	private static final long serialVersionUID = 8642944444967066592L;

	private JTabbedPane loader;

	public Window()
	{
		super();
		JButton button = new JButton("Berechne");
		button.addActionListener(this);
		getContentPane().add(button);
		pack();
		setVisible(true);
		initLoader();
	}

	private void initLoader()
	{
		loader = new JTabbedPane();
		loader.setBackground(Color.LIGHT_GRAY);
		loader.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
		loader.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.GRAY), BorderFactory.createEmptyBorder(2, 2, 2, 2)));
		loader.setSize(new Dimension(600, 65));
		JLayeredPane ebene = getLayeredPane();
		ebene.add(loader, JLayeredPane.POPUP_LAYER);
		setLoaderVisible();
	}

	private void setLoaderVisible()
	{
		if (loader.getTabCount() == 0)
		{
			loader.setVisible(false);
		} else
		{
			loader.setVisible(true);
		}
	}

	public void removeLoaderComponent(final JComponent component)
	{
		SwingWorker worker = new SwingWorker()
		{

			public Object construct()
			{

				return null;
			}

			public void finished()
			{
				loader.remove(component);
				setLoaderVisible();
			}
		};
		worker.start();
	}

	public void setLoaderComponent(final JComponent component)
	{
		SwingWorker worker = new SwingWorker()
		{

			public Object construct()
			{

				return null;
			}

			public void finished()
			{
				loader.addTab("Thread " + (loader.getTabCount() + 1), component);
				loader.setSelectedComponent(component);
				setLoaderVisible();
			}
		};
		worker.start();
	}

	public void actionPerformed(ActionEvent e)
	{
		for (int j = 0; j < 100; j++)
		{
			SwingWorker worker = new SwingWorker()
			{

				public Object construct()
				{
					LoadingScreen s = new LoadingScreen();
					for (int i = 0; i < 100; i++)
						s.setTitle(i + "");
					s.endWithSuccess("Erfolg.");
					return null;
				}

				public void finished()
				{
				}
			};
			worker.start();
		}
	}

}

class WindowClosingAdapter extends WindowAdapter
{

	private boolean exitSystem;

	public WindowClosingAdapter(boolean exitSystem)
	{
		this.exitSystem = exitSystem;
	}

	public void windowClosing(WindowEvent event)
	{
		event.getWindow().setVisible(false);
		event.getWindow().dispose();
		if (exitSystem)
			System.exit(0);
	}
}
Code:
import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

public class LoadingScreen
{

	private static final long serialVersionUID = -5952541571303829093L;

	private static Window mainwindow;

	private JProgressBar statusbar;

	private JLabel title;

	private JPanel panel;

	public LoadingScreen()
	{
		LoadingScreen.mainwindow.setEnabled(false);
		setMainWindowEditable(false);
		title = new JLabel("Aktion wird gestartet...");
		statusbar = new JProgressBar();
		statusbar.setBorderPainted(false);
		statusbar.setStringPainted(true);
		setIndeterminate(true);
		panel = new JPanel(new BorderLayout(5, 5));
		panel.setPreferredSize(new Dimension(550, 40));
		panel.add(title, BorderLayout.NORTH);
		panel.add(statusbar, BorderLayout.CENTER);
		mainwindow.setLoaderComponent(panel);
	}

	public static void setWindow(Window grundFenster)
	{
		LoadingScreen.mainwindow = grundFenster;
	}

	private void setMainWindowEditable(boolean bool)
	{
		if (bool)
			mainwindow.removeLoaderComponent(panel);
		mainwindow.setEnabled(bool);
	}

	public void setProgressMaximum(int max)
	{
		statusbar.setMaximum(max);
	}

	public void setProgress(int prozent)
	{
		setIndeterminate(false);
		statusbar.setValue(prozent);
	}

	public int getProgress()
	{
		return statusbar.getValue();
	}

	public void setTitle(String text)
	{
		title.setText(text);
	}

	public void setIndeterminate(boolean status)
	{
		if (status)
			statusbar.setStringPainted(false);
		else
			statusbar.setStringPainted(true);
		statusbar.setIndeterminate(status);
	}

	public void endWithBugReportAndPause(String fehlermeldung, int seconds)
	{
		setIndeterminate(false);
		setProgress(statusbar.getMaximum());
		for (int i = seconds; i > 0; i--)
		{
			setTitle(fehlermeldung + " Das Fenster schließt in " + i + " Sekunden");
			try
			{
				Thread.sleep(1000);
			} catch (InterruptedException e)
			{
			}
		}
		setMainWindowEditable(true);
	}

	public void endWithBugReportAndPause(String fehlermeldung, Exception exception, int seconds)
	{
		endWithBugReportAndPause(fehlermeldung + " Die Meldung ist: " + exception.getMessage(), seconds);
	}

	public void endWithSuccess(String text)
	{
		if (text != null && !text.equals(""))
		{
			setTitle(text);
		} else
			setTitle("Die Aktion wurde erfolgreich beendet.");
		setProgress(statusbar.getMaximum());
		for (int i = 1; i > 0; i--)
		{
			try
			{
				Thread.sleep(200);
			} catch (InterruptedException e)
			{
			}
		}
		setMainWindowEditable(true);
	}

	public void endWithSuccess(String text, int seconds)
	{
		if (text != null && !text.equals(""))
		{
			setTitle(text);
		} else
			setTitle("Die Aktion wurde erfolgreich beendet.");
		setProgress(statusbar.getMaximum());
		for (int i = seconds; i > 0; i--)
		{
			if (text != null && !text.equals(""))
			{
				setTitle("Die Aktion wurde erfolgreich beendet " + " in " + i + " Sekunden.");
			}
			setTitle(text + " Das Fenster schließt  in " + i + " Sekunden");
			try
			{
				Thread.sleep(1000);
			} catch (InterruptedException e)
			{
			}
		}
		setMainWindowEditable(true);
	}

}
 
G

Guest

Gast
denn hab ich mal im netz aufgegabelt. Verstehen tu ich ihn nicht wirklich, aber funktionieren tut er, denk ich =)
Aber ansonsten wende ich das korrekt an?
 
G

Guest

Gast
So sieht er aus

Code:
import javax.swing.SwingUtilities;

public abstract class SwingWorker
{

	private static class ThreadVar
	{

		private Thread thread;

		ThreadVar(Thread t)
		{
			thread = t;
		}

		synchronized Thread get()
		{
			return thread;
		}

		synchronized void clear()
		{
			thread = null;
		}
	}

	private Object value;

	private ThreadVar threadVar;

	public abstract Object construct();

	public SwingWorker()
	{
		final Runnable doFinished = new Runnable()
		{

			public void run()
			{
				finished();
			}
		};
		Runnable doConstruct = new Runnable()
		{

			public void run()
			{
				try
				{
					setValue(construct());
				}
				catch (Exception e)
				{
					System.err.print("Fehler in neuem Thread: ");
					e.printStackTrace();
				}
				finally
				{
					threadVar.clear();
				}
				SwingUtilities.invokeLater(doFinished);
			}
		};
		Thread t = new Thread(doConstruct);
		threadVar = new ThreadVar(t);
	}

	public void start()
	{
		Thread t = threadVar.get();
		if (t != null)
		{
			t.start();
		}
	}

	public Object get()
	{
		while (true)
		{
			Thread t = threadVar.get();
			if (t == null) { return getValue(); }
			try
			{
				t.join();
			}
			catch (InterruptedException e)
			{
				Thread.currentThread().interrupt();
				return null;
			}
		}
	}

	protected synchronized Object getValue()
	{
		return value;
	}

	private synchronized void setValue(Object x)
	{
		value = x;
	}

	public void finished()
	{
	}

	public void interrupt()
	{
		Thread t = threadVar.get();
		if (t != null)
		{
			t.interrupt();
		}
		threadVar.clear();
	}
}
 

Wildcard

Top Contributor
Wie du siehst wird construct() bei diesem SwingWorker nicht im EDT ausgeführt, die GUI Objekte darfst du also dort nicht anfassen.
 
G

Guest

Gast
Das heißt dann das ist falsch und Loadingscreen darf ich nicht in construct() erzeugen?
Dann kann ich während einer intensiven Berechnung aber nicht die Progressbar updaten..

Code:
...
 SwingWorker worker = new SwingWorker()
         {

            public Object construct()
            {
               [b]LoadingScreen s = new LoadingScreen();[/b]
               for (int i = 0; i < 100; i++)
                  s.setTitle(i + "");
               s.endWithSuccess("Erfolg.");
               return null;
            }

            public void finished()
            {
            }
         };
         worker.start(); 
...

Is so dann besser?
Code:
...
 SwingWorker worker = new SwingWorker()
         {

            public Object construct()
            {
             
            }

            public void finished()
            {
               [b]LoadingScreen s = new LoadingScreen();[/b]
               for (int i = 0; i < 100; i++)
                  s.setTitle(i + "");
               s.endWithSuccess("Erfolg.");
               return null;
            }
         };
         worker.start(); 
...
 

Wildcard

Top Contributor
-Erzeug die Komponente einfach vorher
-verzichte ganz auf den SwingWorker
-nimm den der bei Java dabei ist

Alles drei würde funktionieren
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Buttons anklickbar machen, bzw. Threadproblem AWT, Swing, JavaFX & SWT 5
BabySuna darstellungsprobleme mit JTabbedPane und GridBagLayout AWT, Swing, JavaFX & SWT 8
I JTabbedPane mit DnD, [x]-Schaltfläche, [+]-Schaltfläche usw. AWT, Swing, JavaFX & SWT 1
D JScrollPane in JTabbedPane AWT, Swing, JavaFX & SWT 3
D Kein Icon beim JTabbedPane AWT, Swing, JavaFX & SWT 1
B JTabbedPane Tabs anordnen AWT, Swing, JavaFX & SWT 2
D JTabbedPane GUI Experimente AWT, Swing, JavaFX & SWT 4
N JLabel in JTabbedPane verschieben AWT, Swing, JavaFX & SWT 2
U JScrollPane -> JTabbedPane u.A. AWT, Swing, JavaFX & SWT 3
L JTabbedPane mit for Schleife aufbauen AWT, Swing, JavaFX & SWT 4
J JTabbedPane Vollbild wenn Tabwechsel AWT, Swing, JavaFX & SWT 1
B StateChangeListener auf JTabbedPane AWT, Swing, JavaFX & SWT 5
F jTabbedPane Tabwechsel deaktivieren AWT, Swing, JavaFX & SWT 2
J JTabbedPane: close Button Problem AWT, Swing, JavaFX & SWT 2
J JTabbedPane: table in new tab: tooltip benutzt die column-widths von table in erstem geöffneten tab AWT, Swing, JavaFX & SWT 17
M JTabbedPane verändern mit Nimbus Look and Feel AWT, Swing, JavaFX & SWT 1
F JTabbedPane bestimmten Tab ansprechen AWT, Swing, JavaFX & SWT 13
F JTabbedPane mit Button zum Hinzufügen eines neuen Tabs AWT, Swing, JavaFX & SWT 6
BRoll JTabbedPane setTitleAt OutOfBoundsExc AWT, Swing, JavaFX & SWT 4
K JTabbedPane Tab Markierung / Selektion AWT, Swing, JavaFX & SWT 4
B Custom JTabbedPane-Tab-Design AWT, Swing, JavaFX & SWT 2
L JTabbedPane Closebutton integrieren AWT, Swing, JavaFX & SWT 6
J JTabbedPane Grafik unterhalb der Tabs AWT, Swing, JavaFX & SWT 3
H Swing JTabbedPane: Zusätzliche Buttons neben den Tabs AWT, Swing, JavaFX & SWT 7
V JTabbedPane Eingefügte Labels verschoben AWT, Swing, JavaFX & SWT 2
M Swing JTabbedPane: Tab-Elemente anpassen AWT, Swing, JavaFX & SWT 3
S Swing JTabbedPane: Nur nach ButtonClick und nicht nach Click auf Tab ins nächste Tab wechseln AWT, Swing, JavaFX & SWT 2
P JTabbedPane per Menuitem erstellen AWT, Swing, JavaFX & SWT 20
K Swing JTabbedPane wird nicht angezeigt AWT, Swing, JavaFX & SWT 19
B Swing JTabbedPane in JApplet -> Reiter bei Aktualisation mehrmals zu sehen AWT, Swing, JavaFX & SWT 3
M JTabbedPane -> setSelectedIndex funzt nicht AWT, Swing, JavaFX & SWT 3
D Bestimmtes JPanel innerhalb eines JTabbedPane ansprechen AWT, Swing, JavaFX & SWT 2
M jtabbedpane aktivieren/deaktivieren AWT, Swing, JavaFX & SWT 13
J Swing Letzten Tab einer JTabbedPane ermitteln AWT, Swing, JavaFX & SWT 6
T JTabbedPane - neuen Tab zwischen zwei anderen Tabs hinzufügen AWT, Swing, JavaFX & SWT 2
B Hilfe zu JTable und JTabbedPane AWT, Swing, JavaFX & SWT 18
hdi LookAndFeel Nimbus BUG mit JTabbedPane?! AWT, Swing, JavaFX & SWT 5
hdi Swing Problem mit JTabbedPane AWT, Swing, JavaFX & SWT 2
A LookAndFeel Rollover Effekt bei JTabbedPane deaktivieren (Nimbus) AWT, Swing, JavaFX & SWT 8
T Inhalt von einem Tab an JTabbedPane größe ausrichten? AWT, Swing, JavaFX & SWT 2
S JTabbedPane Problem AWT, Swing, JavaFX & SWT 3
S JTabbedPane AWT, Swing, JavaFX & SWT 4
D JTabbedPane mit Eventlistener versehen? AWT, Swing, JavaFX & SWT 9
M Swing JTabbedPane Panels deaktivieren AWT, Swing, JavaFX & SWT 2
K JTabbedPane setName() für jedes Tab AWT, Swing, JavaFX & SWT 2
G JTabbedPane - Länge der Reiter beeinflussen? AWT, Swing, JavaFX & SWT 9
G Swing JTabbedPane Was für ein Border wird da um die Tabs gezeichnet? AWT, Swing, JavaFX & SWT 6
S Swing Komponentengröße in JTabbedPane AWT, Swing, JavaFX & SWT 7
M Ein Tab eine JTabbedPane durch Button Druck öffen AWT, Swing, JavaFX & SWT 2
Y LookAndFeel JTabbedPane: Tab-Farbe mit Nimbus setzen AWT, Swing, JavaFX & SWT 3
M CloseButton bei JTabbedPane AWT, Swing, JavaFX & SWT 4
P Swing JTabbedPane mit JButton einen anderen Tab anzeigen AWT, Swing, JavaFX & SWT 9
D JTabbedPane zentrieren AWT, Swing, JavaFX & SWT 2
S Swing JTabbedPane: Inhalt soll oben links anfangen AWT, Swing, JavaFX & SWT 6
Mike90 JTabbedPane Größe anpassen AWT, Swing, JavaFX & SWT 17
F JTabbedPane Reiter breite AWT, Swing, JavaFX & SWT 4
B JTabbedPane mit Enumeration dynamisch füllen AWT, Swing, JavaFX & SWT 5
D Swing Tab in JTabbedPane AWT, Swing, JavaFX & SWT 5
A JFrame > JTabbedPane > JPanel > addKeyListener AWT, Swing, JavaFX & SWT 18
D JTabbedPane - Farbe ändern im Bereich hinter den Reitern AWT, Swing, JavaFX & SWT 2
M JTabbedPane - Tab auslesen AWT, Swing, JavaFX & SWT 2
H Swing Problem mit JTabbedPane AWT, Swing, JavaFX & SWT 9
D jtabbedpane Event VOR tab-Wechsel AWT, Swing, JavaFX & SWT 3
S Border von JTabbedpane-Tab? AWT, Swing, JavaFX & SWT 3
M JTabbedPane Docable? AWT, Swing, JavaFX & SWT 3
L Swing JTabbedPane - Index vom Tab AWT, Swing, JavaFX & SWT 3
D Swing JTabbedPane, TabComponent & Popup AWT, Swing, JavaFX & SWT 4
F Borders von JTabbedPane und JScrollPane AWT, Swing, JavaFX & SWT 5
W JTabbedPane Größe anpassen AWT, Swing, JavaFX & SWT 4
G Swing JTabbedPane vergrößern AWT, Swing, JavaFX & SWT 2
H Swing Register (jTabbedPane) dynamisch hinzufügen? AWT, Swing, JavaFX & SWT 7
D Tabs von JTabbedPane stylen AWT, Swing, JavaFX & SWT 6
U JTabbedPane: Layout-Probleme bei addTab zur Laufzeit AWT, Swing, JavaFX & SWT 2
1 JTabbedPane Tab ausdehnen AWT, Swing, JavaFX & SWT 3
F Swing JTabbedPane: Zur Laufzeit die Tabreihenfolge ändern AWT, Swing, JavaFX & SWT 2
M Elemente in JTabbedPane platzieren AWT, Swing, JavaFX & SWT 7
B Swing JFormattedTextField auf mehreren JPanels in einer JTabbedPane AWT, Swing, JavaFX & SWT 3
K LookAndFeel JTabbedPane mit Icon und CloseButton AWT, Swing, JavaFX & SWT 2
D Swing Probleme bei mit JTabbedPane.getChildren() AWT, Swing, JavaFX & SWT 4
I Swing Randnutzung bei JTabbedPane.LEFT AWT, Swing, JavaFX & SWT 2
ABstraCT JTabbedPane - click wird nicht immer ausgeführt ! AWT, Swing, JavaFX & SWT 10
P JTabbedPane und fill? AWT, Swing, JavaFX & SWT 2
D Swing mehrere JTable in separaten Tabs einer JTabbedPane AWT, Swing, JavaFX & SWT 2
G JTabbedPane transparent AWT, Swing, JavaFX & SWT 2
S Swing JTabbedPane: Resize des JFrame bei Tab wechsel AWT, Swing, JavaFX & SWT 8
thE_29 Swing JTabbedPane Focus von Komponenten außerhalb AWT, Swing, JavaFX & SWT 10
S Scrollbar in einem JTabbedPane AWT, Swing, JavaFX & SWT 4
A Schriftfarbe von jTabbedPane und Button Ändern AWT, Swing, JavaFX & SWT 7
R JTabbedPane Selektion verfolgen? AWT, Swing, JavaFX & SWT 2
byte JTabbedPane - Insets entfernen AWT, Swing, JavaFX & SWT 7
S JTabbedPane child setBounds AWT, Swing, JavaFX & SWT 4
J jTabbedPane mit jPanel füllen AWT, Swing, JavaFX & SWT 14
A JTable im JTabbedPane -> Überschriften werden nicht angez AWT, Swing, JavaFX & SWT 2
V Extended JTabbedPane AWT, Swing, JavaFX & SWT 7
V JTabbedPane - keine "Focus"-Box auf selektiertem T AWT, Swing, JavaFX & SWT 2
G JTabbedPane wird groesser wenn man anderen Tab auswaehlt. AWT, Swing, JavaFX & SWT 2
A JTabbedPane Tabwechsel rausfinden AWT, Swing, JavaFX & SWT 2
O JTabbedPane - Selected Color? AWT, Swing, JavaFX & SWT 1
T Wie aktualisiere ich die Contents einer JTabbedPane? AWT, Swing, JavaFX & SWT 3
G JTabbedPane zentiert alles AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben