Frage zu Klassen und swing

Status
Nicht offen für weitere Antworten.

TomFader

Mitglied
hi,

ich versuch für die uni eine art funktionen plotter zu schreiben der nebenbei auch hoch un tiefpunkte brechnet jetzt steh ich ein bischen an.

1) Ich will wenn ich auf den Start Button klick dass sich etwas an der progressbar tut hab auch schon code dafür geschrieben, jedoch tut sich bei mir nichts, woran kann dass liegen? Sprech ich die jProgressbar falsch an?

2) Ich hab mir eine Klasse Rechteck gebastelt und will diese anzeigen lassen, jedoch weiß ich nicht wo genau im Programm ich dass mache? Ich habs zwar versucht scheiter jedoch kläglich dran und bin langsam mit meinem Latein am Ende.

3) Ich mag dann später mal in eben diesem Rechteck zeichnen sprich meine Funktionen darstellen, dazu werd ich mir ein Koordinatensystem basteln und die Punkte der Kurven/Funktionen der Reihe nacht auf das Bild schießen, dass sollte mit BUfferdImage gehn. Jetzt meine Frage gibt es ne einfachere Möglichkeit oder denk ich da zu kompliziert?

Code:
package funktion;

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;
import javax.swing.JTextArea;
import java.awt.Rectangle;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JTextField;


public class gui extends JFrame{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public JPanel jPanel = null;
	public JLabel jLabel = null;
	public JTextField jTextField = null;
	public JButton jButton = null;
	public JProgressBar jProgressBar = null;
	public JLabel jLabel1 = null;
	public JLabel jLabel2 = null;
	public JTextArea jTextArea = null;
	public JPanel jPanel1 = null;
	public Rechteck AnzeigeRechteck = null;
	

	

	/**
	 * This method initializes 
	 * 
	 */
	public gui() {
		super();
		initialize();
	}



	/**
	 * This method initializes this
	 * 
	 */
	private void initialize() {
        this.setSize(new Dimension(500, 400));
        this.setTitle("Graphische Funktionen Zeichner");
        this.setContentPane(getJPanel());
			
	}



	/**
	 * This method initializes jPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel() {
		if (jPanel == null) {
			jLabel2 = new JLabel();
			jLabel2.setBounds(new Rectangle(330, 345, 31, 16));
			jLabel2.setText("100%");
			jLabel1 = new JLabel();
			jLabel1.setBounds(new Rectangle(285, 345, 46, 16));
			jLabel1.setText("Status");
			jLabel = new JLabel();
			jLabel.setBounds(new Rectangle(15, 180, 91, 17));
			jLabel.setText("Funktion f(x)= ");
			jPanel = new JPanel();
			jPanel.setLayout(null);
			jPanel.add(jLabel, null);
			jPanel.add(getJTextField(), null);
			jPanel.add(getJButton(), null);
			jPanel.add(getJProgressBar(), null);
			jPanel.add(jLabel1, null);
			jPanel.add(jLabel2, null);
			jPanel.add(getJTextArea(), null);
			jPanel.add(getJPanel1(), null);
			Rechteck AnzeigeRechteck = new Rechteck();
			jPanel.add(AnzeigeRechteck);
			
			
			
		}
		return jPanel;
	}



	/**
	 * This method initializes jTextField	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJTextField() {
		if (jTextField == null) {
			jTextField = new JTextField();
			jTextField.setBounds(new Rectangle(105, 180, 286, 16));
		}
		return jTextField;
	}



	/**
	 * This method initializes jButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButton() {
		if (jButton == null) {
			jButton = new JButton();
			jButton.setBounds(new Rectangle(405, 180, 76, 16));
			jButton.setText("Start");
			jButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {

					for (int i = 0; i > 100; i++) {
				          // Als Beispiel für eine
				          // rechenintensive Operation
				          try { Thread.sleep(100); } 
				           catch (InterruptedException ex) {}
				          jProgressBar.setValue(i);					        
				          //jButton.setText(String.valueOf(i));
				          jProgressBar.paint(jProgressBar.getGraphics());
					}
					
				}
			});
		}
		return jButton;
	}



	/**
	 * This method initializes jProgressBar	
	 * 	
	 * @return javax.swing.JProgressBar	
	 */
	private JProgressBar getJProgressBar() {
		if (jProgressBar == null) {
			jProgressBar = new JProgressBar();
			jProgressBar.setBounds(new Rectangle(375, 345, 106, 16));
		}
		return jProgressBar;
	}



	/**
	 * This method initializes jTextArea	
	 * 	
	 * @return javax.swing.JTextArea	
	 */
	private JTextArea getJTextArea() {
		if (jTextArea == null) {
			jTextArea = new JTextArea();
			jTextArea.setBounds(new Rectangle(15, 210, 466, 121));
			jTextArea.setText("Funktionszeichenlog:");
		}
		return jTextArea;
	}



	/**
	 * This method initializes jPanel1	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel1() {
		if (jPanel1 == null) {
			jPanel1 = new JPanel();
			jPanel1.setLayout(null);
			jPanel1.setBounds(new Rectangle(135, 15, 226, 151));
		}
		return jPanel1;
	}
	
	public class Rechteck extends Component{

		/**
		 * 
		 */
		private static final long serialVersionUID = -3673149918506320972L;
		int x=50, y=50;
		int width=50, height=50;
		
		public void paint(Graphics g){
			g.setColor(Color.red);
			g.fillRect(x, y, width, height);
		}
		
		public Dimension getPreferredSize(){
			return new Dimension(100, 100);
		}
		
	}


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		gui gui = new gui();
		gui.show();//gui.
		
		
		
	}
}  //  @jve:decl-index=0:visual-constraint="50,119"
 
Klassen groß schreiben, Variablen klein!

-----
nicht Component aus AWT sondern JComponent aus SWING nehmen

----

AnzeigeRechteck braucht Bounds um in null-Layout angezeigt zu werden:
AnzeigeRechteck.setBounds(new Rectangle(10, 10, 110, 110));
-------

public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(x, y, width, height);
}

statt paint

------

böse Fehlerquelle: du definierst eine lokale Variable
Rechteck AnzeigeRechteck = new Rechteck();

die gleichnamige Exemplarvariable bleibt null

-----

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
bei JFrames nicht vergessen

---------

eine GUI kann sich erst wieder zeichnen, wenn ein ActionListener beendet wurde,
längere Aktionen darin müssen in einen Thread

---------

nie getGraphics() von Swing-Komponenten aufrufen (bei dem BufferedImage dagegen vielleicht schon)!
die JProgressBar wird schon automatisch gezeichnet wenn du das mit dem Thread geregelt hast,
was nicht leicht wird für einen Anfänger, ruhig noch nachfragen (morgen oder wer anders erklärt es)

------

3.
klingt vernünftig
 
Hi,

hab jetzt einiges korrigiert und es funktioniert nun viel besser 😉

Was meinst du mit:

"böse Fehlerquelle: du definierst eine lokale Variable
Rechteck AnzeigeRechteck = new Rechteck();

die gleichnamige Exemplarvariable bleibt null "?
Wenn ich dass rausnehmen zeigt er dass Rechteck nicht mehr an.


Hab hetzt sogar die Progressbar soweit hinbekommen, wobei wenn ich jetzt mehrmals auf Start klicke der Thread mehrmals angestossen wird und sich dass ganze zu überalgern beginnt. Kann ich da was dagegen machen? Oder irgendwie die Anzahla n laufenden Threads über den Button begrenzen? Oder den Button disablen?

Hat zu 3 vieleicht noch wer eine Idee oder Anregung wegen den Funktionen die ich im Rechteck ausgeben will?
Es soll dann quasi die gezeichnete mathematische Funktion in diesem Rechte gezeichne werden, inkluse KOordinatensystem und Achsenbeschriftungen, wobei ich am überlegen bin wie ich dass am geschicktesten mache (Buffered Image)?

Code:
package funktion;

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;
import javax.swing.JTextArea;
import java.awt.Rectangle;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import java.awt.*;
import javax.swing.JTextField;


public class gui extends JFrame{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public JPanel jPanel = null;
	public JLabel jLabel = null;
	public JTextField jTextField = null;
	public JButton jButton = null;
	public JProgressBar jProgressBar = null;
	public JLabel jLabel1 = null;
	public JLabel jLabel2 = null;
	public JTextArea jTextArea = null;
	public JPanel jPanel1 = null;
	public Rechteck AnzeigeRechteck = null;
	

	

	/**
	 * This method initializes 
	 * 
	 */
	public gui() {
		super();
		initialize();
	}



	/**
	 * This method initializes this
	 * 
	 */
	private void initialize() {
        this.setSize(new Dimension(500, 400));
        //should be accessed in a static way ???
        this.setDefaultLookAndFeelDecorated(true);
        this.setTitle("Graphische Funktionen Zeichner");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setContentPane(getJPanel());
			
	}



	/**
	 * This method initializes jPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel() {
		if (jPanel == null) {
			jLabel2 = new JLabel();
			jLabel2.setBounds(new Rectangle(330, 345, 31, 16));
			jLabel2.setText("100%");
			jLabel1 = new JLabel();
			jLabel1.setBounds(new Rectangle(285, 345, 46, 16));
			jLabel1.setText("Status");
			jLabel = new JLabel();
			jLabel.setBounds(new Rectangle(15, 180, 91, 17));
			jLabel.setText("Funktion f(x)= ");
			jPanel = new JPanel();
			jPanel.setLayout(null);
			jPanel.add(jLabel, null);
			jPanel.add(getJTextField(), null);
			jPanel.add(getJButton(), null);
			jPanel.add(getJProgressBar(), null);
			jPanel.add(jLabel1, null);
			jPanel.add(jLabel2, null);
			jPanel.add(getJTextArea(), null);
			jPanel.add(getJPanel1(), null);
			Rechteck AnzeigeRechteck = new Rechteck();
			jPanel.add(AnzeigeRechteck);
			AnzeigeRechteck.setBounds(new Rectangle(10, 10, 110, 110));
			
			
			
		}
		return jPanel;
	}



	/**
	 * This method initializes jTextField	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJTextField() {
		if (jTextField == null) {
			jTextField = new JTextField();
			jTextField.setBounds(new Rectangle(105, 180, 286, 16));
		}
		return jTextField;
	}



	/**
	 * This method initializes jButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButton() {
		if (jButton == null) {
			jButton = new JButton();
			jButton.setBounds(new Rectangle(405, 180, 76, 16));
			jButton.setText("Start");
			jButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					new Thread( new Runnable()
					{
					public void run()
					{
					for ( int i = 1; i <= 100; i++ )
					{
					try { Thread.sleep( 100 ); } catch ( InterruptedException e ) { }
					final int j = i;

					SwingUtilities.invokeLater( new Runnable()
					{
					public void run()
					{
						jProgressBar.setValue(j);
						jLabel2.setText(j + "%");
					}				
			});
					 
					}
					}
		}).start();
					}
				});
			
				}
		return jButton;
	}



	/**
	 * This method initializes jProgressBar	
	 * 	
	 * @return javax.swing.JProgressBar	
	 */
	private JProgressBar getJProgressBar() {
		if (jProgressBar == null) {
			jProgressBar = new JProgressBar();
			jProgressBar.setBounds(new Rectangle(375, 345, 106, 16));
		}
		return jProgressBar;
	}



	/**
	 * This method initializes jTextArea	
	 * 	
	 * @return javax.swing.JTextArea	
	 */
	private JTextArea getJTextArea() {
		if (jTextArea == null) {
			jTextArea = new JTextArea();
			jTextArea.setBounds(new Rectangle(15, 210, 466, 121));
			jTextArea.setText("Funktionszeichenlog:");
		}
		return jTextArea;
	}



	/**
	 * This method initializes jPanel1	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel1() {
		if (jPanel1 == null) {
			jPanel1 = new JPanel();
			jPanel1.setLayout(null);
			jPanel1.setBounds(new Rectangle(135, 15, 226, 151));
		}
		return jPanel1;
	}
	
	public class Rechteck extends JComponent{

		/**
		 * 
		 */
		private static final long serialVersionUID = -3673149918506320972L;
		int x=50, y=50;
		int width=50, height=50;
		
		public void paintComponent(Graphics g){
			super.paintComponent(g);
			g.setColor(Color.red);
			g.fillRect(x, y, width, height);
		}
		
		public Dimension getPreferredSize(){
			return new Dimension(100, 100);
		}
		
	}


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		gui gui = new gui();
		gui.show();//gui.
		
		
		
	}
}  //  @jve:decl-index=0:visual-constraint="50,119"
 
du hast eine Exemplarvariable
> public Rechteck AnzeigeRechteck = null

diese bleibt null,

wenn du allerdings
AnzeigeRechteck = new Rechteck();
statt
> Rechteck AnzeigeRechteck = new Rechteck();
schreibst (so wie bereits jetzt schon für jPanel, jLabel usw) dann ist die Exemplarvariable nicht mehr null

----------

du hast die Programmiermacht, den Thread zur jProgressBar zu kontrollieren,
speichere z.B. das Runnable-Objekt in einer Variablen,
prüfe im ActionListener, ob die Variable gesetzt ist, ob das Runnable noch läuft (setzt einen Status fertig = true am Ende der Run-Operation)
lasse das gegebenenfalls aufhören (setze einen Status hoehreAuf, der in der run-Operation in der Schleife berücksichtig wird)
usw., du kannst alles denkbare programmieren

---------

ob BufferedImage oder direkt in das Rechteck zu zeichnen ist doch erstmal egal, das sind am Ende 10 Zeilen Unterschied,

Koordinatensystem malen, x-e und y-e malen, warum sollte es da irgendwas anderes geben?
gibt natürlich fertige Libraries wie JFreeChart,
ansonsten Pixel per Pixel,
ich zumindest kann da nix weiter zu sagen
 
ad1:

ok soweit verstanden denk ich, ich leg vorher eine exemplar variable fest, deswegen kann ich mir dass Rechteck vor AnzeigeRechteck sparen, soweit korrekt?

ad2:

stimmt hätte ich selber drauf kommen können, aber ich hätte gedacht dass es ne eigene Thread Funktion dafür gibt.
Werd mir jetzt halt mal selbst was basteln, wo er zuerst ein runnableFlag setzt und wenn halt ein neuer Thread gestartet wird den alten killt. Wie kann ich einen Thread stoppen? mit Thread.stop() ? Jetzt etwas dass mich leicht verwirrt ich hab ja zeitweise mehrere Threads, wie weiß der Thread der gerade rennt, ob es einen neuen/alten gibt?

ich hab ein runnableFlag und frage dieses im Thread aber wie? ich hab ja mehrere Threads?
/* ich steh da grad ein bisschen auf der Leitung */

ad3:

werd mal Koordinatensystem und Beschriftungen basteln und anzeigen,
ich hoffe der Rest kommt dann von allein. Kennt vieleicht wer eine gute Doku
wo die Koordinaten innerhalb eines Images beschrieben werden? bzw. vlt. näher
auf die berechnung eben dieser eingegangen wird, hab nämlich gelesen dass es
bei Images wohl anders ist als beim normalen GUI.

Soweit mal Dankeschön 😉
 
> kann ich mir dass Rechteck vor AnzeigeRechteck sparen, soweit korrekt?

es geht nicht ums Sparen, sondern darum ob die Exemplarvariable gesetzt ist oder nicht,
später willst du auf AnzeigeRechteck malen,
was machst du wenn das null ist und du auf das Rechteck, welches in der GUI angezeigt wird, keine Referenz hast?

Variablen klein schreiben!

-----------

ich persönlich sehe keinen Sinn in Operationen wie Thread.stop(), auch wenn es sie anscheinend gibt, ja,
setze wie gesagt in Runnable eine boolean-Variable hoehreAuf auf true, in run schaust du in jedem Schleifendurchlauf nach, ob die Variable gesetzt ist und dieser Runnable beendet ganz zivilisiert selber seine Schleife

ein neuer Thread könnte ja nach dem Setzen von hoehreAuf notfalls noch warten bis der andere Thread tatsächlich endlich aufhört hat,

mehrere Threads speicherst du in mehreren einzelnen Variablen oder in einer Liste (bzw. nur die jeweiligen Runnable-Objekte),
prinzipiell ändert sich nichts an der Verarbeitung,
du kannst immer noch jeden Thread nach seinem Zustand fragen/ ihnen mitteilen aufzuhören oder was auch immer

warum du mehr als einen Thread gleichzeitig brauchst verstehe ich allerdings nicht,

denkbar wäre auch, überhaupt nur einen Thread zu verwenden, der nie aufhört sondern nur Pause macht wenn 10 sec vorbei sind
-> wenn in Pause, dann ganz normalen 10 sec-Zyklus anfangen
(mit interrupt() auf den Thread ein sleep() unterbrechen)
-> wenn aktuell in Arbeit, dann von vorne anfangen oder was auch immer
 
@ Thread im Endeffekt brauch ich nur einen Thread, damit er da die Berechnung der Werte macht und auf dass Rechteck schießt und halt während er rechntet die Statusbar mit zieht.

@ exepmlar variable:

"es geht nicht ums Sparen, sondern darum ob die Exemplarvariable gesetzt ist oder nicht,
später willst du auf AnzeigeRechteck malen,
was machst du wenn das null ist und du auf das Rechteck, welches in der GUI angezeigt wird, keine Referenz hast?

Variablen klein schreiben!"

Dass versteh ich jetzt nicht, kannst du ein kleines Beispiel geben damit ich check was gemeint ist? Ich steh da total an, also ich versteh so halb was du meinst, aber wüsste jetzt nicht wie ich es korrekt ändern kann? Vlt. ne Schleife rein bauen wie bei den anderen objekten (zB.: Button).
 
Code:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test
{
    private String a;
    private String b;

    public Test()
    {
        a = "x"; 
        String b = "y";
    }

    public void z()
    {
        System.out.println("a: " + a); // a ist im Konstruktor gesetzt
        System.out.println("b: " + b); // b ist null
    }


    public static void main(String[] args)
        throws Exception
    {

        Test t = new Test();
        t.z();

    }


}
 
@ Thread:

Hab dass jetzt so gelöst dass ich den Button von jButton.setEnabled(true); auf jButton.setEnabled(false); setze.

Damit kann ihn der User nicht mehr anklicken und sieht auch optisch ganz schön dass er warten muss bis der mitm berechnen fertig ist.

dass ganze Code Snippeit schaut dann so aus, keine Ahnung ob es ne bessere Möglichkeit gibt:

Code:
jButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					jButton.setEnabled(false);
					new Thread( new Runnable()
					{
						public void run()
						{
							for ( int i = 1; i <= 100; i++ )
							{
								try { Thread.sleep( 100 ); } catch ( InterruptedException e ) { }
								final int j = i;

								SwingUtilities.invokeLater( new Runnable()
								{
									public void run()
									{
										jProgressBar.setValue(j);
										jLabel2.setText(j + "%");
										if (j==100)
										{
											jButton.setEnabled(true);
											jLabel2.setText("");
										}
									}
									
									
								});

							}
							
						}
						
					}).start();

				}
			});

@Rechteck: Jetzt steh ich mal an beim Punkte am Rechteck ausgeben/zeichnen.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben