Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    Finestra bianca all'apertura, se ridimensiono appare tutto

    Salve a tutti,
    ho creato un primo semplice programma in java e funziona, a parte uno stupido problema.
    Il programma ha delle etichette, dei jtextfield, dei jradiobutton e dei bottoni. Molto semplicemente inserendo dei dati applica delle formule matematiche e ne restituisce altri. Questo funziona senza problemi.
    Il problema sta nel fatto che aprendo il programma alcune volte appare tutto bianco, altre volte si vedono solo delle etichette, altre volte si vede qualche elemento in più... poi se ridimensiono la finestra (anche di pochissimo) appare tutto. La cosa assurda è che va a caso, alcune volte riesco a vedere tutti gli elementi senza ridimensionarla!

    Da che dipende? Non so che informazioni possano essere utili quindi sono stato molto vago, fatemi sapere cosa potrebbe servire

  2. #2
    Utente di HTML.it
    Registrato dal
    Oct 2014
    residenza
    Padova
    Messaggi
    361
    Per caso aggiungi qualche componente dopo aver richiamato sul frame il metodo setVisible() ? Potrebbe essere quello il problema ma senza il codice io non saprei dire molto di più...

  3. #3
    risolto in un attimo, grazie avevo messo setVisible(true) proprio all'inizio del codice prima di aggiungere i componenti ma non avrei mai pensato fosse quello il problema proprio perchè a volte caricava l'interfaccia grafica e a volte no... com'è possibile una cosa del genere?
    poichè sono agli inizi sto programmando "per gruppi": scrivo tutto ciò che riguarda la finestra e lascio un paio di righe vuote, poi scrivo tutto ciò che riguarda bottone1 e lascio un pò di spazio etc. Come conviene fare invece? Mi interessa saperlo sia per uniformarmi a dei canoni sia per evitare problemi come questo del setVisible in futuro. (Al momento l'ho messo come ultima riga per verificarne il funzionamento ma non mi sembra ordinato).

  4. #4
    Utente di HTML.it
    Registrato dal
    Oct 2014
    residenza
    Padova
    Messaggi
    361
    Quote Originariamente inviata da ixol Visualizza il messaggio
    non avrei mai pensato fosse quello il problema proprio perchè a volte caricava l'interfaccia grafica e a volte no... com'è possibile una cosa del genere?
    Non sono espertissimo di swing ma ho imparato che aggiornare l'interfaccia grafica una volta costruita è una faccenda molto delicata (tanto per dirne una va fatta fare dall'EDT, ci sono molte discussioni a riguardo qui sul forum).
    Quindi è sempre opportuno rendere visibile un frame solo come ultima istruzione, dopo averlo costruito del tutto.

    Quote Originariamente inviata da ixol Visualizza il messaggio
    Come conviene fare invece? Mi interessa saperlo sia per uniformarmi a dei canoni sia per evitare problemi come questo del setVisible in futuro. (Al momento l'ho messo come ultima riga per verificarne il funzionamento ma non mi sembra ordinato).
    Ripeto che aggiungerlo come ultima riga è assolutamente appropriato, anzi è buona prassi non inserire nemmeno l'istruzione nel costruttore del frame, ma rendere visibile il frame dal punto in cui lo si richiama (a patto che il tuo frame estenda la classe JFrame, che è sempre consigliabile), qualcosa di questo tipo:

    codice:
    new MyFrame(/* eventuali parametri*/).setVisible(true);
    In questo modo ti assicuri che la finestra sia visualizzata solo dopo che ogni componente è stato effettivamente creato.

    Ci sono altre indicazioni generali: come detto è bene che la tua classe estenda JFrame per poter ereditare tutti i metodi e le caratteristiche di un JFrame (sarebbe da evitare l'uso di frame statici memorizzati in classi che non c'entrano nulla, sempre meglio abituarsi a programmare ad oggetti).

    Un'altra cosa che ti consiglierà chiunque (nella stragrande maggioranza dei casi) è imparare a usare i LayoutManager per posizionare i componenti, quindi evitare l'uso di metodi come setBounds().
    Per chiudere il frame è opportuno invece richiamare il metodo pack() su di esso.

    L'ordine con cui aggiungi i componenti o modifichi le caratteristiche della finestra è abbastanza irrilevante a mio parere, ma è sempre bene seguire un buon ordine logico e non "fare a caso".

    Personalmente a me piace definire subito il comportamento della finestra (caratteristiche come setResizable(false) , setDefaultCloseOperation(DISPOSE_ON_CLOSE)) e poi parto dall'alto a costruire i pannelli di cui ho bisogno e man mano ad aggiungerci i componenti.
    Metto qualche stupida riga di codice per dare un'idea, ma questa è una cosa che impari con l'esperienza o guardando esempi un po' più complessi (ad esempio il nostro andbin ha una ricca collezione di esempi su Swing ) :


    codice:
    import java.awt.*;
    import javax.swing.*;
    public class MyFrame extends JFrame
    {
        public MyFrame()
        {
            // Caratteristiche della finestra
            super("Titolo del frame");
            setDefaultCloseOperation(DISPOSE_ON_CLOSE);
            setResizable(false);
            // Creo i vari pannelli
            Container pane=getContentPane(); // prendi il contenitore a cui aggiungere i vari pannelli
            pane.setBackground(Color.WHITE);
            JPanel topPanel=new JPanel(new FlowLayout(FlowLayout.CENTER,20,0));
            JPanel bottomPanel=new JPanel();
            topPanel.setBackground(Color.WHITE);
            bottomPanel.setBackground(Color.WHITE);
            bottomPanel.setLayout(new BoxLayout(bottomPanel,BoxLayout.Y_AXIS));
            // Pannello superiore
            topPanel.add(new JLabel("Il FlowLayout"));
            topPanel.add(new JLabel("dispone gli elementi in un'unica riga"));        
            // Pannello inferiore    
            Box firstBox=Box.createHorizontalBox(),secondBox=Box.createHorizontalBox();
            firstBox.setBorder(BorderFactory.createEmptyBorder(10,5,15,0));
            firstBox.add(new JLabel("Con il BoxLayout ad esempio"));
            secondBox.setBorder(BorderFactory.createEmptyBorder(30,140,5,0));
            secondBox.add(new JLabel("Puoi ottenere effetti piu' complessi"));
            bottomPanel.add(firstBox);
            bottomPanel.add(secondBox);
            pane.add(topPanel,BorderLayout.NORTH);
            pane.add(bottomPanel,BorderLayout.SOUTH);
            // Chiudo il frame e lo centro nello schermo
            pack();
            setLocationRelativeTo(null);
        }
        public static void main(String[] a)
        {
            SwingUtilities.invokeLater(new Runnable(){
                public void run()
                {
                    try{
                        new MyFrame().setVisible(true);
                    }
                    catch(Exception e){
                        e.printStackTrace();
                    }
                }
            });
        }
    }
    Per qualsiasi cosa non esitare a chiedere
    Ultima modifica di Ansharja; 20-04-2016 a 20:28

  5. #5
    mh se faccio come hai suggerito tu esce una finestra priva di dimensioni e contenuti

  6. #6
    Utente di HTML.it
    Registrato dal
    Oct 2014
    residenza
    Padova
    Messaggi
    361
    Quote Originariamente inviata da ixol Visualizza il messaggio
    mh se faccio come hai suggerito tu esce una finestra priva di dimensioni e contenuti
    Se hai seguito quello che faccio nell'esempietto che ho messo sopra questo non dovrebbe succedere.Questo ammesso che tu abbia:

    - aggiungo tutti i componenti al contentPane del JFrame
    - richiamato il metodo pack() sul JFrame
    - richiamato il metodo setVisible(true) sul JFrame

    esattamente in questo ordine.Se compili ed esegui il codice sopra infatti dovresti ottenere un frame molto simile a questo (cambia un po' a seconda del sistema operativo):

    frame.png

    Ricontrolla se hai fatto tutto in quell'ordine, se il problema persiste però dovresti iniziare a postare il codice che crea problemi, non è così facile aiutare ad occhi chiusi
    Ultima modifica di Ansharja; 21-04-2016 a 16:32

  7. #7
    Le uniche differenze dal tuo codice sono che ho creato una nuova classe per il main (ho letto in giro su internet che conviene farlo) e che non uso il metodo pack() perchè ho un gridlayout e avrei una finestra priva di dimensioni.

    In ogni caso posto il codice:
    codice:
    import java.awt.Color;import java.awt.Container;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.BorderFactory;
    import javax.swing.ButtonGroup;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JRadioButton;
    import javax.swing.JTextField;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import javax.swing.border.LineBorder;
    import javax.swing.SwingConstants;
    
    
    public class Finestra extends JFrame{
        Container mainContainer;
        JTextField mazzo, carte, percentuale;
        JRadioButton primo, secondo;
    
    
        public Finestra() {
            JFrame window = new JFrame("Calcolo Probabilità");
            window.setSize(347, 228);
            window.setResizable(false);
            window.setLocationRelativeTo(null);
            window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    
            mainContainer = window.getContentPane();
            mainContainer.setLayout(new GridLayout(5, 2));
            
            JPanel panelMazzo1 = new JPanel();
            mainContainer.add(panelMazzo1);
            JLabel labelMazzo = new JLabel("Numero di carte nel mazzo:");
            panelMazzo1.add(labelMazzo);
            
            JPanel panelMazzo2 = new JPanel();
            mainContainer.add(panelMazzo2);
            mazzo = new JTextField();
            mazzo.setPreferredSize(new Dimension(6, 24));
            mazzo.setColumns(5);
            mazzo.setBorder(BorderFactory.createLineBorder(Color.BLACK));
            panelMazzo2.add(mazzo);
            
            JPanel panelCarte1 = new JPanel();
            mainContainer.add(panelCarte1);
            JLabel labelCarte = new JLabel("<html>Numero di carte di cui<br>calcolare la probabilità:</html>");
            panelCarte1.add(labelCarte);
            
            JPanel panelCarte2 = new JPanel();
            mainContainer.add(panelCarte2);
            carte = new JTextField();
            carte.setPreferredSize(new Dimension(6, 24));
            carte.setColumns(5);
            carte.setBorder(BorderFactory.createLineBorder(Color.BLACK));
            panelCarte2.add(carte);
            
            JPanel panelPartenza1 = new JPanel();
            mainContainer.add(panelPartenza1);
            JLabel labelPartenza = new JLabel("Partenza:");
            panelPartenza1.add(labelPartenza);
            
            JPanel panelPartenza2 = new JPanel();
            mainContainer.add(panelPartenza2);
            ButtonGroup group = new ButtonGroup();
            primo = new JRadioButton("Primo", true);
            secondo = new JRadioButton("Secondo");
            group.add(primo);
            group.add(secondo);
            panelPartenza2.add(primo);
            panelPartenza2.add(secondo);
            
            JPanel panelBottoni1 = new JPanel();
            mainContainer.add(panelBottoni1);
            JButton calcola = new JButton("Calcola");
            calcola.addActionListener(new clickBottone());
            panelBottoni1.add(calcola);
            
            JPanel panelBottoni2 = new JPanel();
            mainContainer.add(panelBottoni2);
            JButton reset = new JButton("Reset");
            panelBottoni2.add(reset);
            reset.addActionListener(new resetBottone());
            
            JPanel panelPercentuale1 = new JPanel();
            mainContainer.add(panelPercentuale1);
            panelPercentuale1.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
            JLabel labelPercentuale = new JLabel("Percentuale:");
            panelPercentuale1.add(labelPercentuale);
            
            JPanel panelPercentuale2 = new JPanel();
            mainContainer.add(panelPercentuale2);
            percentuale = new JTextField();
            percentuale.setHorizontalAlignment(SwingConstants.CENTER);
            percentuale.setPreferredSize(new Dimension(6, 24));
            percentuale.setEditable(false);
            percentuale.setColumns(4);
            panelPercentuale2.add(percentuale);
            percentuale.setBorder(new LineBorder(new Color(0, 0, 0), 0));
            
            //window.setVisible(true);
        }
    
    
        private class clickBottone implements ActionListener {
            public void actionPerformed(ActionEvent e){
                int p=0,n,c;
                float val=1;
                try{
                    n=Integer.valueOf(mazzo.getText() );
                    c=Integer.valueOf(carte.getText() );
                    if(n<=60 && c<=n && c>=0){
                        if(secondo.isSelected()) p=1;
                        for(int i=0;i<5+p;i++){
                            val=val*(n-c)/n;
                            n--;
                        }
                        val=Math.round((1-val)*1000);
                        val/=10;
                        String str=val+"%";
                        percentuale.setText(str);
                        percentuale.setBackground(Color.red);
                    }else{
                        JOptionPane.showMessageDialog(null, "Valori inseriti errati");
                    }
                }catch(Exception exc){
                    JOptionPane.showMessageDialog(null, "Valori inseriti errati");        
                }
                
            }
        }
    
    
        private class resetBottone implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                mazzo.setText("");
                carte.setText("");
                primo.setSelected(true);
                percentuale.setBackground(Color.white);
                percentuale.setText("");
            }
        }
    
    
    }
    codice:
    
    public class Principale {
    public static void main(String[] args) {
        Finestra finestra1 = new Finestra();
        finestra1.setVisible(true);
    }
    }
    Già che ci sei se noti qualcosa che faccio che però conviene fare diversamente fammelo notare, vorrei imparare anche lo "stile di scrittura" di un codice.
    Ultima modifica di ixol; 21-04-2016 a 17:43

  8. #8
    Ciao, vedo un paio di cose sbagliate concentrate in poche righe di codice
    codice:
    public class Finestra extends JFrame{
        Container mainContainer;
        JTextField mazzo, carte, percentuale;
        JRadioButton primo, secondo;
    
    
    
    
        public Finestra() {
            JFrame window = new JFrame("Calcolo Probabilità Yugioh");
    a) Tutti questi qui dovrebbero essere private, ovvero usabili solo nella stessa classe.
    private Container mainContainer;
    private JTextField mazzo, carte, percentuale;
    private JRadioButton primo, secondo;


    b)
    codice:
      public class Finestra extends JFrame
        ....
        ....
            public Finestra() {
            JFrame window = new JFrame("Calcolo Probabilità Yugioh");
            window.setSize(347, 228);
            window.setResizable(false);
            window.setLocationRelativeTo(null);
            window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    E' inutile istanziare una variabile JFrame (window) che dichiari e poi estendi finestra
    dovresti fare una cosa del genere
    codice:
      public class Finestra extends JFrame
        ....
        ....
            public Finestra() {
            super("Calcolo Probabilità Yugioh");
            this.setSize(347, 228);
            this.setResizable(false);
            this.setLocationRelativeTo(null);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    
            mainContainer = this.getContentPane();
            mainContainer.setLayout(new GridLayout(5, 2));
    inoltre parte di queste funzioni solitamente si dichiarano alla fine.

    Direi che ti conviene fare un mainPanel che ti contenga tutti i tuoi panelli e poi aggiungerne solo uno al JFrame, è una gestione più lineare.


    Ciao.
    Ultima modifica di schumy2000; 21-04-2016 a 17:47
    I computer sono incredibilmente veloci, accurati e stupidi.
    Gli uomini sono incredibilmente lenti, inaccurati e intelligenti.
    Insieme sono una potenza che supera l'immaginazione.

    A.Einstein

  9. #9
    Utente di HTML.it
    Registrato dal
    Oct 2014
    residenza
    Padova
    Messaggi
    361
    Quote Originariamente inviata da ixol Visualizza il messaggio
    Le uniche differenze dal tuo codice sono che ho creato una nuova classe per il main (ho letto in giro su internet che conviene farlo) e che non uso il metodo pack() perchè ho un gridlayout e avrei una finestra priva di dimensioni.
    La classe per il Main va benino, se guardi l'esempio che ho fatto io l'invocazione del frame viene fatta da SwingUtilities.invokeLater(), il perché lo puoi trovare facilmente online, riguarda quello che accennavo prima sull'EDT (in realtà in questa parte sono anch'io abbastanza alle prime armi).

    Invece il metodo pack() devi usarlo, altrimenti è chiaro che il tuo frame non avrà dimensioni.Puoi anche specificarle tu manualmente, richiamando sul JFrame il metodo setSize(int w,int h), ma è molto meglio lasciare che il sia il frame stesso a calcolare le proprie dimensioni.

    Il motivo per cui tu non vedi nulla è un errore abbastanza semplice: hai esteso correttamente JFrame nella classe Finestra, quindi l'oggetto costruito dal costruttore è effettivamente un JFrame, che poi rendi visibile dalla classe principale.

    Ma all'interno del costruttore invece che aggiungere tutti i pannelli e settare le proprietà direttamente sull'oggetto che stai istanziando, aggiungi tutto a una variabile window, che poi non rendi mai visibile !

    Come dicevo non ha alcun senso mantenere una variabile di tipo JFrame all'interno della tua classe, è proprio l'oggetto Finestra il tuo frame! Quindi ad esempio le righe:

    codice:
    JFrame window = new JFrame("Calcolo Probabilità Yugioh");
    window.setSize(347, 228);
    window.setResizable(false);
    window.setLocationRelativeTo(null);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    vanno modificate in :

    codice:
    super("Calcolo Probabilità Yugioh"); // stai richiamando il costruttore della superclasse JFrame direttamente sul tuo oggetto !!
    setSize(347, 228);
    setResizable(false);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    Questa parte è cruciale e senza comprendere questo non vai molto avanti.Nella prima riga, come scritto nel commento, richiami il costruttore di JFrame, e da quel momento tutte le caratteristiche vengono applicate direttamente alla tua Finestra (con i metodi setSize(),setResizable() ecc.).

    Quindi la tua variabile window non serve assolutamente a niente, va tutto applicato all'oggetto che stai costruendo.

    Vedrai che se modifichi questo aspetto e inserisci come ultima riga nel costruttore il metodo pack(), tutto quello che hai creato e aggiunto all'oggetto viene correttamente visualizzato.

    Altri consigli: i metodi pack() e setLocationRelativeTo(null) vanno richiamati dopo aver costruito tutto il frame.
    Il motivo è semplice: pack() richiude il contenitore con tutto quello che è inserito, mentre setLocationRelativeTo(null) è un modo per centrare il frame nello schermo, e sarebbe meglio farlo quando esso è già correttamente dimensionato.

    Per il resto vedo che usi molti (troppi a mio parere) pannelli per un'interfaccia abbastanza semplice, ma qui si tratta di usare bene i layout e il design non è un aspetto così immediato e facile da padroneggiare.
    Per ora modifica quelle cose, al massimo poi si riparlerà dello "stile di scrittura", tieni comunque conto che ognuno ha il proprio stile e io non sono certo un professionista, tanto per dirne una comunque io odio a morte il GridLayout e non lo utilizzo mai

    [EDIT]: accidenti battuto dal veloce schumy di poco , comunque non abbiamo scritto cose così diverse
    Ultima modifica di Ansharja; 21-04-2016 a 17:49

  10. #10
    Si Ansharja l'unica differenza sta nel "this"
    Il this sta ad indicare la classe JFrame ereditata
    Quando estendi una classe eredita tutti i metodi quindi quel this si può mettere od omettere non fà differenza in questo caso.
    Ciao.
    I computer sono incredibilmente veloci, accurati e stupidi.
    Gli uomini sono incredibilmente lenti, inaccurati e intelligenti.
    Insieme sono una potenza che supera l'immaginazione.

    A.Einstein

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.