Koordinatenkreuz an die Fenstergrösse anpassen

Mohikan

Grünschnabel
Hallo!

Ich bin neu im Forum und bitte erstmal um Verständnis, wenn meine Frage unklar ist:

Ich abe ein Programm geschrieben, dass ein Fenster erzeugt. In diesem Fenster ist nur ein Button nämlich "refresh" zu finden. Durch Klick auf Button soll das mathematische Koordinatensystem gezeichnet werden. Ich habe alles hinbekommen.

Mein Problem: Wenn ich das Fenster durch Ziehen oder einfach durch Klick auf das Symbol Maximieren oben rechts des Fensters vergrössere, möchte ich, dass meine Grafik auch vergrössert wird. Gibt es eine Methode, die das ermöglicht oder muss dass anders realisiert werden.

Zur Lösung habe ich versucht die Grösse des bildPanel, aus das meine Grafik gezeichnet werden soll, abzufragen, und dann mit diesen Größen das Koordinatensystem zu zeichnen. Ich bekomme aber als Größe immer den Wert 0.

Start.java
PHP:
package deneme;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


public class Start
	{	
	String st,st1;
		@SuppressWarnings("deprecation")
		public static  void main(String[] args)
		{
			SimpleFrame frame=new SimpleFrame();
	        frame.show();
		}
		/*public void setString1(String string1, String string2) {
	        this.st =string1;
	        this.st1 =string2;
	           
	    }*/
	}	
		
class SimpleFrame extends JFrame 
	{
	
	private static final long serialVersionUID = 1L;
	int WIDTH;
	int HEIGHT;
	public SimpleFrame()
			{ 
		WIDTH=400;
		HEIGHT=400;
			setSize(WIDTH,HEIGHT);
			setEnabled(true); 
			
			//fenster kann nicht vergrößert werden
			//setResizable(false);
			DrawPanel panel=new DrawPanel();
			Container contentPane=getContentPane();
			contentPane.add(panel);	
			
			addWindowListener(new WindowAdapter(){
    	    	public void windowClosing(WindowEvent e){
    	    	    System.exit(0);
    	    	}
    	    });						
		}		
	}
	
class DrawPanel extends JPanel {	
		private static final long serialVersionUID = 1L;
	   //private MyCanvas can;
	   JButton refreshButton;
	   JPanel bottomPanel;
	   JPanel bildPanel;
	   GridLayout layout;
	   Diagramm bild;
	 public DrawPanel()
		{
		  //can = new MyCanvas();
	      //can.setBounds(0,0,WIDTH, HEIGHT-30);
	      //can.setBackground(Color.lightGray);
		 setLayout(new BorderLayout());
		 bottomPanel=new JPanel();
		 add(bottomPanel,BorderLayout.SOUTH);
		 bildPanel=new JPanel();
		 add(bildPanel,BorderLayout.CENTER);
		 bildPanel.setLayout(new GridLayout(0,1));
 	 
		 refreshButton=new JButton("refresh");
		 bottomPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
 		 bottomPanel.add(refreshButton);
 		//add(bottomPanel,"South");
 		//add(bildPanel,"Center");
		 //panel1.add(bild);
 	    //add(can,BorderLayout.CENTER);
	    //add(can);	
    	  
         refreshButton.addActionListener(new ActionListener(){
       		public void actionPerformed(ActionEvent e){
       			if(e.getSource() == refreshButton) {
       		        bild = new Diagramm();
       		        //bild.setString(st,st1);   
       		        //bild.setBounds(0,0,new SimpleFrame().WIDTH-50,new SimpleFrame().HEIGHT-50);
       		     bild.setBounds(0,0,bildPanel.getWidth()-50,bildPanel.getHeight()-50);
       		        bildPanel.add(bild);
       		        //add(bild);
       		        bild.repaint();
       		        bild.setVisible(true);        		        }
        			}
    	         });
		  }
	 /*public double panelGroesse(){
		 Dimension x=  bildPanel.getSize();
		 return x.getWidth();
	 }*/
	 }

Diagramm.java
PHP:
package deneme;

//import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
//import java.awt.geom.AffineTransform;
//import java.awt.geom.Rectangle2D;

import javax.swing.JPanel;

public class Diagramm extends JPanel{

    private static final long serialVersionUID = 1L;
	int w=new SimpleFrame().getWidth();
	int h=new SimpleFrame().getHeight();
	//int x=new DrawPanel().bildPanel.getWidth();
	//int h=new DrawPanel().bildPanel.getHeight();
	
		public void paint(Graphics graphics) { 
			//System.out.println(new DrawPanel().panelGroesse());
			Graphics2D g = (Graphics2D) graphics;
			//AffineTransform tx = new AffineTransform(1, 0, 0, -1, 0, getHeight()); 
			//AffineTransform tx = new AffineTransform();
			//tx.rotate(Math.PI);
			//g.setTransform( tx ); 
			g.setColor(Color.black);
			g.translate(20, 20);
			g.drawLine(0,h-150, w-150, h-150);//x-achse
			g.fillArc(w-150, h-165, 30, 30, 165, 30); //horizontaler Pfeil
			g.drawString("time",250 , 250);
		    g.drawLine(0,h-150, 0, 0);//y-achse
		    g.fillArc(-15, -20, 30, 30, 255, 30); //vertikaler Pfeil
		    g.drawString("modul",0 , 0);
		    
		      }
		
}
 
Die Größe Deines Diagramm-Panels kriegst Du mittels getWidth() und getHeight() raus, die von JPanel geerbt werden.
Nebenbei ist Dein Layout sehr kompliziert: setz für SimpleFrame ein BorderLayout und pack Dein Diagramm ins Zentrum (BorderLayout.CENTER) und den Refresh-Button in die untere Zeile (BorderLayout.SOUTH).

Ach ja: bitte für Java-Code JAVA-Tags verwenden :)
 
Danke für die schnelle Antwort, aber diese Methoden ergeben nur die richtige Werte, wenn man die im start.java verwendet. Ich brauche aber diese Werte im diagramm.java. Ich hatte den Aufruf dieser Methoden im diagramm.java auskommentiert. Warum ergeben sich diese Methoden immer den Wert 0.

Ich habe mein Layout vereinfacht und werde hier nochmal einfügen. Jetzt nich mehr als PHP Code aber auch nicht als als java tags, denn ich weiss nicht, wie das ist. sorry

Ich will aber beide Klassen behalten, d.h. die paint Methode im diagramm.java will ich nicht in start.java übertragen. Noch mal zu meinem Ziel: das Koordinatensystem soll auch größer werden wenn das Fenster vergrössert wird. Deswegen habe ich gedacht, wenn ich die Größen des bildPanels bekomme, dann wird das Diagramm nach diesen Werten gezeichnet. Ob das möglich ist weiß ich noch nicht.

vielen Dank im voraus

start.java
Code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Start extends JFrame
	{	
	   JButton refreshButton;
	   JPanel buttonPanel;
	   JPanel bildPanel;
	   Diagramm bild;
	   
	   private static final long serialVersionUID = 1L;
		@SuppressWarnings("deprecation")
		public static  void main(String[] args)
		{
			Start frame=new Start();
	        frame.show();
		}		
		

	public Start()
			{
			final int WIDTH=400;
			final int HEIGTH=400;
			setSize(WIDTH,HEIGTH);
			setEnabled(true);

			Container contentPane=getContentPane();
			setLayout(new BorderLayout());
			buttonPanel=new JPanel();
			contentPane.add(buttonPanel);
			add(buttonPanel,BorderLayout.SOUTH);
			bildPanel=new JPanel();
			contentPane.add(bildPanel);
			add(bildPanel,BorderLayout.CENTER);
			refreshButton=new JButton("refresh");
		    buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    		
			buttonPanel.add(refreshButton);
    	    addWindowListener(new WindowAdapter(){
    	    	public void windowClosing(WindowEvent e){
    	    	    System.exit(0);
    	    	}
    	    });						
    	    
    	    refreshButton.addActionListener(new ActionListener(){
    	    	public void actionPerformed(ActionEvent e){
           			if(e.getSource() == refreshButton) {
           		        bild = new Diagramm();   
           		        bild.setBounds(0,0,350,300);
           		        bildPanel.add(bild); 
           		        bild.repaint();
           		        bild.setVisible(true);        		        }
            			}
        	         });
    	  }
}

diagramm.java
Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;

public class Diagramm extends JPanel{

    private static final long serialVersionUID = 1L;
	//int w=new Start().bildPanel.getWidth(); ergibt 0
	//int h=new Start().bildPanel.getHeight(); ergibt 0
	
		public void paint(Graphics graphics) { 
			//System.out.println(w); Breite liefern
			Graphics2D g = (Graphics2D) graphics;
			g.setColor(Color.black);
			g.translate(20, 20);
			g.drawLine(0,250, 250, 250);//x-achse
			g.fillArc(250, 235, 30, 30, 165, 30); //horizontaler Pfeil
			g.drawString("time",250 , 250);
		    g.drawLine(0,250, 0, 0);//y-achse
		    g.fillArc(-15, -20, 30, 30, 255, 30); //vertikaler Pfeil
		    g.drawString("modul",0 , 0);
		    
		      }		
}
 
Zuletzt bearbeitet:
Hallo

Obwohl ich nicht machen wollte, sehe ich ein, dass es nicht anders geht.
Ich habe also diagramm.java gelöscht und die paint Methode in start.java gespeichert.
Jetzt ging es mit dem Vergrössern des Koordinatensystems.

Jetzt aber folgendes Problem: Vergrössern ist leider nicht reibungslos, d.h. ich muss das Fenster ausblenden dann einblenden. Ich will aber auf einem Klick erledigen.

Wie kann ich das bitte korrigieren? wieder sorry wegen php code :-(

start.java
PHP:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Start extends JFrame
	{	
	   JButton refreshButton;
	   JPanel buttonPanel;
	   JPanel bildPanel;
	   Diagramm bild;
	   
	   private static final long serialVersionUID = 1L;
		@SuppressWarnings("deprecation")
		public static  void main(String[] args)
		{
			Start frame=new Start();
	        frame.show();
		}		
		

	public Start()
			{
			final int WIDTH=400;
			final int HEIGTH=400;
			setSize(WIDTH,HEIGTH);
			setEnabled(true);
			
			Container contentPane=getContentPane();
			setLayout(new BorderLayout());
			buttonPanel=new JPanel();
			contentPane.add(buttonPanel);
			add(buttonPanel,BorderLayout.SOUTH);
			bildPanel=new JPanel();
			contentPane.add(bildPanel);
			add(bildPanel,BorderLayout.CENTER);
			refreshButton=new JButton("refresh");
		    buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    		
			buttonPanel.add(refreshButton);
    	    addWindowListener(new WindowAdapter(){
    	    	public void windowClosing(WindowEvent e){
    	    	    System.exit(0);
    	    	}
    	    });						
    	    
    	    refreshButton.addActionListener(new ActionListener(){
    	    	public void actionPerformed(ActionEvent e){
           			if(e.getSource() == refreshButton) { 
           				repaint();}
            			}
        	         });
    	  }
	public void paint(Graphics graphics) { 
		int w=bildPanel.getWidth();
	    int h=bildPanel.getHeight();
		Graphics2D g = (Graphics2D) graphics;
		g.setColor(Color.black);
		g.translate(20, 20);
		g.drawLine(0,h-100, w-150, h-100);//x-achse
		g.fillArc(w-150, h-115, 30, 30, 165, 30); //horizontaler Pfeil
		g.drawString("time",w-150 , h-150);
	    g.drawLine(0,h-100, 0, 0);//y-achse
	    g.fillArc(-15, -20, 30, 30, 255, 30); //vertikaler Pfeil
	    g.drawString("modul",0 , 0);
	    
	      }		
}
 
Du kannst auch deine alte Klasse nehmen nur solltest du die etwas umschreiben

Code:
public class Diagramm extends JPanel{

    private static final long serialVersionUID = 1L;
	
	public void paint(Graphics graphics) { 
	           int w = getWidth(); // Diese Methodem direkt in die Paint rein
	           int h = getHeight(); // und dann die Größe deines Panels ermitteln
                                ...

	      }		
}
 
Erstmal danke für den Vorschlag. Habe probiert und bekomme beim ersten Klick auf Button richtige Werte, aber wenn ich das Fenster vergrössere, geht das Koordinatensystem verloren. Um zu sehen, welche Werte die getWidth() und getHeight() ermitteln habe ich System.out.println() in paint-Methode. Der ermitelt wie gesagt den ersten Wert des bildPanels richtig , dann immer den Wert 10 und deswegen geht das Bild verloren. Zur Sauberkeit füge ich den Code nochmal hinzu:

Für weitere Vorschläge bin ich sehr dankbar.

Start.java

PHP:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Start extends JFrame
	{	
	   JButton refreshButton;
	   JPanel buttonPanel;
	   JPanel bildPanel;
	   Diagramm bild;
	   
	   private static final long serialVersionUID = 1L;
		@SuppressWarnings("deprecation")
		public static  void main(String[] args)
		{
			Start frame=new Start();
	        frame.show();
		}		
		

	public Start()
			{
			final int WIDTH=400;
			final int HEIGTH=400;
			setSize(WIDTH,HEIGTH);
			setEnabled(true);
			
			Container contentPane=getContentPane();
			setLayout(new BorderLayout());
			buttonPanel=new JPanel();
			contentPane.add(buttonPanel);
			add(buttonPanel,BorderLayout.SOUTH);
			bildPanel=new JPanel();
			contentPane.add(bildPanel);
			add(bildPanel,BorderLayout.CENTER);
			refreshButton=new JButton("refresh");
		    buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    		
			buttonPanel.add(refreshButton);
    	    addWindowListener(new WindowAdapter(){
    	    	public void windowClosing(WindowEvent e){
    	    	    System.exit(0);
    	    	}
    	    });						
    	    
    	    refreshButton.addActionListener(new ActionListener(){
    	    	public void actionPerformed(ActionEvent e){
           			if(e.getSource() == refreshButton) { 
           				bild = new Diagramm();
           		        //bild.setString(st,st1);   
           		        bild.setBounds(0,0,bildPanel.getWidth()-50,bildPanel.getHeight()-50);
           		        bildPanel.add(bild);
           		        bild.repaint();
           		        bild.setVisible(true); 
           		        }
            			}
        	         });
    	  }
	}
	/*public void paint(Graphics graphics) { 
		int w=bildPanel.getWidth();
	    int h=bildPanel.getHeight();
	    System.out.println(h);
		Graphics2D g = (Graphics2D) graphics;
		g.setColor(Color.black);
		g.translate(20, 20);
		g.drawLine(0,h-150, w-150, h-150);//x-achse
		g.fillArc(w-150, h-165, 30, 30, 165, 30); //horizontaler Pfeil
		g.drawString("time",w-150 , h-150);
	    g.drawLine(0,h-150, 0, 0);//y-achse
	    g.fillArc(-15, -20, 30, 30, 255, 30); //vertikaler Pfeil
	    g.drawString("modul",0 , 0);
	    }*/

Diagramm.java
PHP:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;

public class Diagramm extends JPanel{

    private static final long serialVersionUID = 1L;
	
		public void paint(Graphics graphics) {
			int w=getWidth();
		    int h=getHeight();
			System.out.println(w);
			Graphics2D g = (Graphics2D) graphics;
			g.setColor(Color.black);
			g.translate(20, 20);
			g.drawLine(0,h-150, w-150, h-150);//x-achse
			g.fillArc(w-150, h-165, 30, 30, 165, 30); //horizontaler Pfeil
			g.drawString("time",w-150 , h-150);
		    g.drawLine(0,h-150, 0, 0);//y-achse
		    g.fillArc(-15, -20, 30, 30, 255, 30); //vertikaler Pfeil
		    g.drawString("modul",0 , 0);
		    
		      }		
}
 
Das Problem liegt in der Verwendung des LayoutManagers. Schau Dir einfach noch ein paar Tutorials bzgl. Swing-Layouts an, dann weisst Du, wie der Hase läuft ;-)

Für Dein Beispiel genügt es, dem Fenster (d.h. seiner ContentPane) ein BorderLayout zuzuweisen. Dein Diagramm platzierst Du im Center - dieser Bereich passt sich einer veränderten Fenstergröße an - und den Button z.B. im unteren Bereich (SOUTH, ist so groß wie für die beinhalteten Elemente nötig).

Java:
    public Start() {
        super("Diagramm-Test");
        setSize(400, 400);

        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());

        bild = new Diagramm();
        contentPane.add(bild, BorderLayout.CENTER);

        refreshButton = new JButton("refresh");
        contentPane.add(refreshButton, BorderLayout.SOUTH);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        refreshButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == refreshButton) {
                    bild.repaint();
                }
            }
        });
        
        setVisible(true);
    }

PS: JAVA bzw. /JAVA in eckigen Klammern verwenden :)
 
Zuletzt bearbeitet:
1000 mal danke matdacat,

zumindest ist das Problem mit dem Vergrössern gelöst, aber muss ich sagen, dass ein anderes Problem aufgetaucht ist und zwar das Diagramm soll erst nach dem Klicken auf refresh angezeigt werden. In deinem Fall ist das nicht so, ich weiss auch woran das liegt. bild=new Diagramm() ist jetzt ausserhalb der ActionListener und es wird sofort angezeigt ohne zu klicken. Na ja ich werde versuchen, es rauszubekommen.
Vielleicht sollte ich das Programm umändern.

Noch eine Frage:
Ich wollte eigentlich als nächster Schritt den Bereich wo das Diagramm angezeigt wird, umgerahmt darstellen oder anders ausgedrückt das Panel umrahmen und dann diagramm anzeigen. Ich hatte deswegen bildPanel erzeugt und versucht mit GridBagLayout das zu kriegen, habe aber nicht hinbekommen. Die inset() Methode gibt es nur für GridBagLayout, zumindest habe ich nicht anderes gefunden. Könnt ihr vielleicht mir dazu einen Tip geben?

viele Grüsse
 
Du könntest eine Variable einführen, um das Diagramm ein- und auszublenden, siehe unten. Bei einem Klick auf "Refresh" rufst Du dann einfach setDiagramVisible(true) auf.
Bzgl. Rahmen: Da Dein Diagramm ja ein JPanel ist, verfügt es über die Methode setBorder. Damit ein von Dir gesetzter Rahmen dann auch sichtbar ist, musst Du in der paint-Methode dafür sorgen, dass auch das paint des JPanels aufgerufen wird (super.paint).

Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;

public class Diagramm extends JPanel{

    private static final long serialVersionUID = 1L;
    
        private boolean diagramVisible = false;
    
        public Diagramm() {
            super();
            setBorder(BorderFactory.createLineBorder(Color.BLACK, 3));
        }
        
        public void setDiagramVisible(boolean visible) {
            diagramVisible = visible;
            repaint();
        }
    
        public void paint(Graphics graphics) {
            super.paint(graphics);
            if (diagramVisible) {            
                int w=getWidth();
                int h=getHeight();
                Graphics2D g = (Graphics2D) graphics;
                g.setColor(Color.black);
                g.translate(20, 20);
                g.drawLine(0,h-150, w-150, h-150);//x-achse
                g.fillArc(w-150, h-165, 30, 30, 165, 30); //horizontaler Pfeil
                g.drawString("time",w-150 , h-150);
                g.drawLine(0,h-150, 0, 0);//y-achse
                g.fillArc(-15, -20, 30, 30, 255, 30); //vertikaler Pfeil
                g.drawString("modul",0 , 0); 
            }
        }        
}

Freu mich über eine gute Bewertung, wenn Dir damit geholfen ist! :)
 
Hallo matdacat,
nochmal vielen Dank. Du hast mir viel geholfen.
Mit dem Rahmen meinte ich eigentlich Hervorhebung, aber ich habe dadurch etwas neues gelernt. Den Rest werde ich selber versuchen zu erledigen und wenn ich in den weiteren Schritten noch Probleme habe, melde ich mich unter anderem Thema.
Eine gute Bewertung hast du selbstverständlich verdient, falls ich finde wo das ist.

Viele Grüsse und schönen Abend
 

Neue Beiträge

Zurück