Disegnare un piano cartesiano con Graphics

di il
13 risposte

Disegnare un piano cartesiano con Graphics

Sto creando un'applicazione in Java per il Desktop su Eclipse, una cosa molto semplice da 1° elementare. L'applicazione ha una JComboBox con 2 o 3 record. Scegliendo il primo record vorrei disegnare una prima figura, scegliendo il secondo record vorrei disegnare una seconda figura. Quello che non so è il tipo di oggetto che devo aggiungere al layout per creare il piano cartesiano. Per ora ho un GridLayout con 5 righe. All'ultima riga vorrei aggiungere questo piano cartesiano che dovrebbe adattarsi allo spazio restante della finestra di dimensione 700 x 700. Questo elemento E vorrei poi poterlo aggiungere alla mia finestra in questo modo:
pannello1.add(E);
pannello1 è un semplice JPanel su cui ho impostato il GridLayout a 6 righe.

13 Risposte

  • Re: Disegnare un piano cartesiano con Graphics

    iBaffiPro ha scritto:


    Quello che non so è il tipo di oggetto che devo aggiungere al layout per creare il piano cartesiano.
    Di per sé, la cosa più semplice/tipica è estendere JPanel e effettuare del custom painting ridefinendo il:
    protected void paintComponent(Graphics g)

    Chiaramente presuppone di sapere di cosa si tratta, quali implicazioni, ecc...
  • Re: Disegnare un piano cartesiano con Graphics

    Riesci a mandarmi un esempio perché quello che scrivi non mi aiuta molto?
    Se ti serve il codice per capire posso postarlo qui, è un programmino con una classe sola.
  • Re: Disegnare un piano cartesiano con Graphics

    Questo è un esempio basilare. Poi se si vuole disegnare le due freccette degli assi e altro, si può.
    import java.awt.Color;
    import java.awt.Graphics;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class FrameProva extends JFrame {
        private PianoCartesiano pianoCartesiano;
    
        public FrameProva() {
            super("Prova PianoCartesiano");
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setSize(500, 400);            // solo come dimensione di esempio
            setLocationRelativeTo(null);  // solo per centrare la finestra nello schermo
    
            pianoCartesiano = new PianoCartesiano();
            add(pianoCartesiano);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> {
                new FrameProva().setVisible(true);
            });
        }
    }
    
    class PianoCartesiano extends JPanel {
        public PianoCartesiano() {
            setBackground(Color.WHITE);
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
    
            int width = getWidth();
            int height = getHeight();
            int xCenter = width / 2;
            int yCenter = height / 2;
    
            g.drawLine(0, yCenter, width-1, yCenter);   // asse X
            g.drawLine(xCenter, 0, xCenter, height-1);  // asse Y
        }
    }
  • Re: Disegnare un piano cartesiano con Graphics

    Grazie mille, mentre hai risposto ho provato a modificare il mio progetto cercando di disegnare un quadrato nell'ultimo pannello ma non capisco perché il nuovo pannello non si adatta alla finestra.
    InterfacciaGraficaConMain.java
    
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Font;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingConstants;
    import javax.swing.SwingUtilities;
    
    import finestra.JavaPaintUI.Panel2;
    
    public class InterfacciaGraficaConMain extends JFrame {
    
    	public static void main(String[] args) {
    		SwingUtilities.invokeLater(new Runnable() {
    			public void run() {
    				InterfacciaGraficaConMain interfaccia = new InterfacciaGraficaConMain();
    				interfaccia.setVisible(true);
    			}
    		});
    	}
    	
    	private static final long serialVersionUID = 1L;
    	protected static final JFrame InterfacciaGraficaVotazioni = null;
    	private Font carattere = new Font("Tahoma", 0, 12);
    	
    	private InterfacciaGraficaConMain() {
    		
    				setSize(800, 600);
    				setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    				setLocationRelativeTo(null);
    				setTitle("Rappresentazione di poligoni");
    								
    				JPanel pannello1 = new JPanel();
    				GridLayout gl = new GridLayout(5, 1);
    				pannello1.setLayout(gl);
    				JLabel JL_titolo = new JLabel("Titolo ...");
    				JLabel JL_sottotitolo = new JLabel("Sottotitolo...");
    				JL_titolo.setHorizontalAlignment(SwingConstants.CENTER);
    				// 1° riga
    				pannello1.add(JL_titolo);
    				JL_sottotitolo.setHorizontalAlignment(SwingConstants.CENTER);
    				JL_sottotitolo.setFont(carattere);
    				// 2° riga
    				pannello1.add(JL_sottotitolo);
    				JLabel JL_descrizione = new JLabel("Rappresentazione di poligoni con la classe Graphics di Java.");
    				JL_descrizione.setHorizontalAlignment(SwingConstants.CENTER);
    				JL_descrizione.setFont(carattere);
    				// 3° riga
    				pannello1.add(JL_descrizione);
    				// Pannello con il JComboBox di scelta
    				JPanel pannello2 = new JPanel();
    				pannello2.setLayout(new FlowLayout());
    				JLabel JL_nota = new JLabel("Tipo di poligono: ");
    				JL_nota.setFont(carattere);
    				JComboBox JCB_scelte = new JComboBox();
    				JCB_scelte.addItem("Quadrato");
    				JCB_scelte.addItem("Triangolo");
    				JCB_scelte.addItem("Cerchio");
    				JCB_scelte.setSelectedIndex(0);
    				JCB_scelte.addActionListener(new ActionListener() {
    					public void actionPerformed(ActionEvent evt) {
    						seleziona_JTF_editabili(evt);
    					}
    					private void seleziona_JTF_editabili(ActionEvent evt) {
    						int campi_selezionabili = JCB_scelte.getSelectedIndex();
    						System.out.println(campi_selezionabili);
    					}
    				});
    				// 1° colonna	
    				pannello2.add(JL_nota);
    				// 2° colonna
    				pannello2.add(JCB_scelte);
    				// 4° riga
    				pannello1.add(pannello2);
    				// 5° riga
    				// Rettagolo
    				JPanel2 JPanel2 = new JPanel2();
    				JPanel2.setBackground(new java.awt.Color(255, 255, 255));
    				pannello1.add(JPanel2);
    				getContentPane().add(pannello1, BorderLayout.NORTH);
    				
    				
    
    	}
    	
    }
    
    JPanel2.java
    
    import java.awt.Dimension;
    import java.awt.Graphics;
    
    import javax.swing.JPanel;
    
    public class JPanel2 extends JPanel {
    	
    	JPanel2() {
    		setSize(200, 200);
        }
    	
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawString("Quadrato", 20, 20);
            g.drawRect(20, 50, 20, 20);
        }
    
    }
    
  • Re: Disegnare un piano cartesiano con Graphics

    Ho risolto in questo modo:
    import java.awt.BorderLayout;
    import java.awt.FlowLayout;
    import java.awt.Font;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingConstants;
    import javax.swing.SwingUtilities;
    
    public class InterfacciaGraficaConMain extends JFrame {
    
    	public static void main(String[] args) {
    		SwingUtilities.invokeLater(new Runnable() {
    			public void run() {
    				InterfacciaGraficaConMain interfaccia = new InterfacciaGraficaConMain();
    				interfaccia.setVisible(true);
    			}
    		});
    	}
    	
    	private static final long serialVersionUID = 1L;
    	protected static final JFrame InterfacciaGraficaVotazioni = null;
    	private Font carattere = new Font("Tahoma", 0, 12);
    	
    	private InterfacciaGraficaConMain() {
    		
    				setSize(800, 600);
    				setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    				setLocationRelativeTo(null);
    				setTitle("Rappresentazione di poligoni");
    								
    				JPanel pannello1 = new JPanel();
    				GridLayout gl = new GridLayout(5, 1);
    				pannello1.setLayout(gl);
    				JLabel JL_titolo = new JLabel("Titolo ...");
    				JLabel JL_sottotitolo = new JLabel("Sottotitolo...");
    				JL_titolo.setHorizontalAlignment(SwingConstants.CENTER);
    				// 1° riga
    				pannello1.add(JL_titolo);
    				JL_sottotitolo.setHorizontalAlignment(SwingConstants.CENTER);
    				JL_sottotitolo.setFont(carattere);
    				// 2° riga
    				pannello1.add(JL_sottotitolo);
    				JLabel JL_descrizione = new JLabel("Rappresentazione di poligoni con la classe Graphics di Java.");
    				JL_descrizione.setHorizontalAlignment(SwingConstants.CENTER);
    				JL_descrizione.setFont(carattere);
    				// 3° riga
    				pannello1.add(JL_descrizione);
    				// Pannello con il JComboBox di scelta
    				JPanel pannello2 = new JPanel();
    				pannello2.setLayout(new FlowLayout());
    				JLabel JL_nota = new JLabel("Tipo di poligono: ");
    				JL_nota.setFont(carattere);
    				JComboBox<String> JCB_scelte = new JComboBox<String>();
    				JCB_scelte.addItem("Quadrato");
    				JCB_scelte.addItem("Triangolo");
    				JCB_scelte.addItem("Cerchio");
    				JCB_scelte.setSelectedIndex(0);
    				JCB_scelte.addActionListener(new ActionListener() {
    					public void actionPerformed(ActionEvent evt) {
    						seleziona_JTF_editabili(evt);
    					}
    					private void seleziona_JTF_editabili(ActionEvent evt) {
    						int campi_selezionabili = JCB_scelte.getSelectedIndex();
    						System.out.println(campi_selezionabili);
    					}
    				});
    				// 1° colonna	
    				pannello2.add(JL_nota);
    				// 2° colonna
    				pannello2.add(JCB_scelte);
    				// 4° riga
    				pannello1.add(pannello2);
    				// 5° riga
    				// Rettagolo
    				JPanel2 JPanel2 = new JPanel2();
    				JPanel2.setBackground(new java.awt.Color(255, 255, 255));
    				//pannello1.add(JPanel2);
    				getContentPane().add(pannello1, BorderLayout.NORTH);
    				getContentPane().add(JPanel2);
    
    	}
    	
    }
    
    però non ho capito perché non posso mettere questo JPanel2 dentro pannello1.
  • Re: Disegnare un piano cartesiano con Graphics

    iBaffiPro ha scritto:


    però non ho capito perché non posso mettere questo JPanel2 dentro pannello1.
    Perché hai usato setSize, questa è la dimensione fisica, reale del componente. Ma se ci sono in gioco i layout manager, sono LORO che computano la dimensione fisica del componente basandosi su varie logiche che possono anche usare 3 altre proprietà: il minimumSize, il maximumSize e il preferredSize.

    Il tuo JPanel2 non ha un preferredSize (ce l'ha ma sicuramente 0x0). Impostalo.
  • Re: Disegnare un piano cartesiano con Graphics

    Avevo già provato a scrivere questo:
    package finestra;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import javax.swing.JPanel;
    public class JPanel2 extends JPanel {
        JPanel2() {
            setPreferredSize(new Dimension(300,300));
        }
        @Override
        public void paintComponent(Graphics g) {
            ...
        }
    }
    ma questa dimensione viene applicata a tutta la griglia, non al solo JPanel2.
  • Re: Disegnare un piano cartesiano con Graphics

    iBaffiPro ha scritto:


    ma questa dimensione viene applicata a tutta la griglia, non al solo JPanel2.
    Hai usato GridLayout, suddivide EQUAMENTE l'area del componente tra tutte le celle-componenti contenuti.
    Il pannello che ha GridLayout è nella parte NORTH del content-pane. In questa area NORTH viene rispettato solo il preferredHeight del componente. La larghezza delle celle NON dipende dalle celle ma dalla larghezza del content-pane e transitivamente dalla larghezza della finestra.
    L'altezza delle celle invece dipende dal preferredHeight. Ma siccome c'è un GridLayout che suddivide equamente, se l'altezza massima ce l'ha il JPanel2 (300), tutti gli altri avranno anche 300.
  • Re: Disegnare un piano cartesiano con Graphics

    Sempre grazie, quindi lascio come ho fatto inizialmente che funziona. Se hai qualche idea migliore la testo.
  • Re: Disegnare un piano cartesiano con Graphics

    Qual è la tecnica per far comparire/scomparire un oggetto del JFrame?
    package finestra;
    
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Font;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingConstants;
    import javax.swing.SwingUtilities;
    
    public class InterfacciaGraficaConMain extends JFrame {
    
    	public static void main(String[] args) {
    		SwingUtilities.invokeLater(new Runnable() {
    			public void run() {
    				InterfacciaGraficaConMain interfaccia = new InterfacciaGraficaConMain();
    				interfaccia.setVisible(true);
    			}
    		});
    	}
    	
    	private static final long serialVersionUID = 1L;
    	protected static final JFrame InterfacciaGraficaConMain = null;
    	private Font carattere = new Font("Tahoma", 0, 12);
    	private PianoCartesiano PianoCartesiano = new PianoCartesiano();
    	private Quadrato Quadrato = new Quadrato();
    	
    	private InterfacciaGraficaConMain() {
    		
    				setSize(800, 600);
    				setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    				setLocationRelativeTo(null);
    				setTitle("Rappresentazione di poligoni");
    								
    				JPanel pannello1 = new JPanel();
    				GridLayout gl = new GridLayout(5, 1);
    				pannello1.setLayout(gl);
    				JLabel JL_titolo = new JLabel("Titolo ...");
    				JLabel JL_sottotitolo = new JLabel("Sottotitolo...");
    				JL_titolo.setHorizontalAlignment(SwingConstants.CENTER);
    				// 1° riga
    				pannello1.add(JL_titolo);
    				JL_sottotitolo.setHorizontalAlignment(SwingConstants.CENTER);
    				JL_sottotitolo.setFont(carattere);
    				// 2° riga
    				pannello1.add(JL_sottotitolo);
    				JLabel JL_descrizione = new JLabel("Rappresentazione di poligoni con la classe Graphics di Java.");
    				JL_descrizione.setHorizontalAlignment(SwingConstants.CENTER);
    				JL_descrizione.setFont(carattere);
    				// 3° riga
    				pannello1.add(JL_descrizione);
    				// Pannello con il JComboBox di scelta
    				JPanel pannello2 = new JPanel();
    				pannello2.setLayout(new FlowLayout());
    				JLabel JL_nota = new JLabel("Tipo di poligono: ");
    				JL_nota.setFont(carattere);
    				JComboBox<String> JCB_scelte = new JComboBox<String>();
    				JCB_scelte.addItem("Scegli il poligono");
    				JCB_scelte.addItem("Quadrato");
    				JCB_scelte.addItem("Triangolo");
    				JCB_scelte.addItem("Cerchio");
    				JCB_scelte.setSelectedIndex(0);
    				JCB_scelte.addActionListener(new ActionListener() {
    					public void actionPerformed(ActionEvent evt) {
    						seleziona_JTF_editabili(evt);
    					}
    					private void seleziona_JTF_editabili(ActionEvent evt) {
    						int campi_selezionabili = JCB_scelte.getSelectedIndex();
    						System.out.println(campi_selezionabili);
    						switch(campi_selezionabili) {
    						case 0:
    							PianoCartesiano.setVisible(true);
    							Quadrato.setVisible(false);
    						break;
    						case 1:
    							PianoCartesiano.setVisible(false);
    							Quadrato.setVisible(true);
    						break;
    						case 2:
    							PianoCartesiano.setVisible(false);
    							Quadrato.setVisible(true);
    						break;
    						case 3:
    							PianoCartesiano.setVisible(false);
    							Quadrato.setVisible(true);
    						break;
    						default:
    							PianoCartesiano.setVisible(true);
    							Quadrato.setVisible(false);
    						}
    					}
    				});
    				// 1° colonna	
    				pannello2.add(JL_nota);
    				// 2° colonna
    				pannello2.add(JCB_scelte);
    				// 4° riga
    				pannello1.add(pannello2);
    				getContentPane().add(pannello1, BorderLayout.NORTH);
    				// 5° riga (vuota)
    				// Parte 2
    				PianoCartesiano.setBackground(new java.awt.Color(255, 255, 255));
    				Quadrato.setBackground(new java.awt.Color(255, 255, 255));
    				getContentPane().add(Quadrato);
    				getContentPane().add(PianoCartesiano);
    
    	}
    	
    }
    
    package finestra;
    
    import java.awt.Graphics;
    
    import javax.swing.JPanel;
    
    public class Quadrato extends JPanel {
    
    	@Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            
            int width = getWidth();
            int height = getHeight();
            int xCenter = width / 2;
            int yCenter = height / 2;
    
            g.drawLine(0, yCenter, width-1, yCenter);   // asse X
            g.drawLine(xCenter, 0, xCenter, height-1);  // asse Y
            
            g.drawString("Quadrato", 20, 20);
            g.drawRect(20, 50, 200, 200);
            
        }
    
    }
    
    
    package finestra;
    
    import java.awt.Graphics;
    
    import javax.swing.JPanel;
    
    public class PianoCartesiano extends JPanel {
    
    	@Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            
            int width = getWidth();
            int height = getHeight();
            int xCenter = width / 2;
            int yCenter = height / 2;
    
            g.drawLine(0, yCenter, width-1, yCenter);   // asse X
            g.drawLine(xCenter, 0, xCenter, height-1);  // asse Y
    
            
        }
    
    }
    
    
    Forse capisco l'errore (i JPanel non inclusi nel JFrame non potranno mai essere visibili) e per risolvere ho provato ad usare remove() ma non funziona.
    Inoltre mi piacerebbe aggiungere dei JTextField che mi permettano di scegliere centro e dimensioni del mio quadrato.
    Consigli?
  • Re: Disegnare un piano cartesiano con Graphics

    iBaffiPro ha scritto:


    Qual è la tecnica per far comparire/scomparire un oggetto del JFrame?
    Ne esistono diverse di tecniche, non solo una. Dipende dal contesto.

    iBaffiPro ha scritto:


    [/code]
    Forse capisco l'errore (i JPanel non inclusi nel JFrame non potranno mai essere visibili) e per risolvere ho provato ad usare remove() ma non funziona.
    remove() da solo non basta se c'è un layout manager. Cioè è corretto fare contenitore.remove(componente); ma se il contenitore ha un layout manager, questo deve essere "validato" di nuovo. Con i layout manager più semplici (es. FlowLayout, BorderLayout ecc...) basta un contenitore.validate(); dopo il remove.

    iBaffiPro ha scritto:


    Inoltre mi piacerebbe aggiungere dei JTextField che mi permettano di scegliere centro e dimensioni del mio quadrato.
    Consigli?
    Comunque, non mi è chiara una cosa: perché hai fatto 2 componenti differenti che disegnano entrambi gli assi e poi Quadrato disegna solo qualcosa in più?
    Se l'obiettivo è quello di aggiungere/cambiare qualcosa su quel piano cartesiano, NON è questo l'approccio sensato scambiando componenti (è difficile, dispendioso, ecc...). Si agisce invece su COSA si disegna nel paintComponent.
  • Re: Disegnare un piano cartesiano con Graphics

    Riesci ad indicarmi uno script che illustri la tecnica?
    Il codice che sto usando l'ho trovato su Internet, di mio pugno non saprei scrivere molto.
    grazie infinite
  • Re: Disegnare un piano cartesiano con Graphics

    iBaffiPro ha scritto:


    Riesci ad indicarmi uno script che illustri la tecnica?
    Riguardo il disegno? Non mi è chiaro il tuo obiettivo: disegnare una sola figura che può cambiare di volta in volta? Disegnare N figure man mano? E quali figure esattamente?
Devi accedere o registrarti per scrivere nel forum
13 risposte