Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    JPanel non viene ridisegnato con nullLayout

    Salve a tutti. Sto creando un applicazione di draw e ho riscontrato un problema. Il mio scopo per ora era quello di creare una GUI che mostrasse un foglio sopra un tavolo a la power point. Mi spiego meglio: il foglio (implementato con un JPanel con un rapporto height/width come quello di un A4) deve essere posizionato all'interno (con un layout nullo) di un altro JPanel (il tavolo appunto) che risulta essere poco più grande (in modo da vedere i bordini). Quando si allarga la finestra della mia applicazione il foglio deve adattarsi alle dimensioni del tavolo mantenendo le giuste proporzioni e restando centrato. Inoltre ho aggiunto una funzione di zoom implementata con un JScrollPane a cui è stato aggiunto il pannello tavolo. Ogni volta che si clicca "zoom in" le dimensioni del pannello tavolo vengono scalate e in questo modo appaiono le scrollBar. Il tutto funziona se allargo la finestra. Al contraio con lo zoom o il ristringimento della finestra le dimensioni del tavolo sono aggiornate in maniera corretta mentre quelle del foglio no. Se decremento lo zoom però il foglio si ridisegna correttamente. E' proprio questo il punto: non riesco a ridisegnare correttamente il foglio. Come posso fare secondo voi? Ho provato i vari repaint / validate / revalidate ma nada Grazie se avete letto tutto questo posto

    Inoltre se nella classe tavolo ovverriddo il metodo paintComponent aggiungendo oltre a super.paintComponent(g) anche il mio adjustDimension tutto funziona :/ ma questa soluzione la vedo molto poco chiara nonchè uno spreco di risorse

    Per i masochisti posto anche il codice:
    Classe tavolo:
    codice:
    package com.wordpress.c4py;
    
    import java.awt.Color;
    import java.awt.Dimension;
    import javax.swing.JPanel;
    
    public class Desk extends JPanel {
    
        /**
         * The percentage of the distance between the desk and the page.
         */
        public static final int BORDER_OFFSET = 3;
        private int zoom = 100;
        private Page currentPage;
        private ScrollableDesk scrollDesk;
        private int fullScreenStatus = FullScreen.FULL_SCREEN_OFF;
    
        /**
         * Standard constructor for Desk Class. It set only graphics properties of
         * the panel.
         */
        public Desk(ScrollableDesk scrollDesk) {
            this.scrollDesk = scrollDesk;
    
            this.setBackground(Color.LIGHT_GRAY);
            this.setLayout(null);
    
            setDisplayedPage(new Page(0)); //FOR DEBUGGING
        }
    
        public void adjustDimension() {
            if (fullScreenStatus == FullScreen.JUST_EXITED_FULL_SCREEN) {
                scrollDesk.setViewportView(this);
                zoomIn();
                fullScreenStatus = FullScreen.FULL_SCREEN_OFF;
            } else if (fullScreenStatus == FullScreen.FULL_SCREEN_OFF) {
                zoomIn();
            }
    
            currentPage.adjustDimension(this.getDimOffsetted());
            centrePage();
        }
    
        public void setFullScreenStatus(int status) {
            fullScreenStatus = status;
            adjustDimension();
        }
    
        /**
         * This method returns the dimension of the desk without borders.
         *
         * @return The Dimension class indicating the dimension of the desk without
         * borders.
         */
        public Dimension getDimOffsetted() {
            int width = this.getWidth() * (100 - BORDER_OFFSET * 2) / 100;
            int height = this.getHeight() * (100 - BORDER_OFFSET * 2) / 100;
    
            return new Dimension(width, height);
        }
    
        /**
         * This method returns the class Page associated with this desk.
         *
         * @return The class Page associated with this desk.
         */
        public Page getDisplayedPage() {
            return currentPage;
        }
    
        /**
         * Set the page that has to be displayed on the desk.
         *
         * @param pageToDisplay The page to display.
         */
        public void setDisplayedPage(Page pageToDisplay) {
            if (currentPage != null) {
                this.remove(currentPage);
            }
            currentPage = pageToDisplay;
            this.add(currentPage);
        }
    
        /**
         * Set the zoom associated with this desk. It can set ony values >=100.
         *
         * @param zoom The zoom associated with this desk. Only values >=100 are
         * accepted.
         */
        public void setZoom(int zoom) {
            this.zoom = zoom;
            adjustDimension();
        }
    
        /**
         * Get the zoom associated with this desk.
         *
         * @return The zoom associated with this desk.
         */
        public int getZoom() {
            return zoom;
        }
    
        private void centrePage() {
            int x = this.getWidth() / 2 - currentPage.getWidth() / 2;
            int y = this.getHeight() / 2 - currentPage.getHeight() / 2;
    
            currentPage.setLocation(x, y);
        }
    
        private void zoomIn() {
            double height = scrollDesk.getViewportBorderBounds().getHeight() * zoom / 100;
            double width = scrollDesk.getViewportBorderBounds().getWidth() * zoom / 100;
    
            if (width < height / Page.A4_RATIO) {
                height = width * Page.A4_RATIO;
            } else {
                width = height / Page.A4_RATIO;
            }
    
            this.setPreferredSize(new Dimension((int) width, (int) height));
            scrollDesk.revalidate();
        }
    }
    Classe foglio:
    codice:
    package com.wordpress.c4py;
    
    import java.awt.Color;
    import java.awt.Dimension;
    import javax.swing.BorderFactory;
    import javax.swing.JPanel;
    
    public class Page extends JPanel {
    
        private int number;
        /**
         * The constant indicating the ratio between the height and the width of a
         * horizontal A4.
         */
        public static final float A4_RATIO = 210.0f / 297.4f;
    
        /**
         * Standard constructor for class Page.
         *
         * @param number The number of page that specifies time.
         */
        public Page(int number) {
            this.number = number;
    
            this.setBackground(Color.WHITE);
            this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        }
    
        /**
         * Adjust the dimension of the page according with the dimension of the
         * desk.
         *
         * @param dimDesk The Dimension of the desk on wich lays the page without
         * the offset part. (= Desk.getDimOffseted())
         * @see Desk
         */
        public void adjustDimension(Dimension dimDesk) {
            double height;
            double width;
    
            if (dimDesk.getWidth() < dimDesk.getHeight() / A4_RATIO) {
                width = dimDesk.getWidth();
                height = width * A4_RATIO;
            } else {
                height = dimDesk.getHeight();
                width = height / A4_RATIO;
            }
    
            this.setSize(new Dimension((int) width, (int) height));
        }
    }
    classe zoom (JScrollPane):
    codice:
    package com.wordpress.c4py;
    
    import java.awt.event.ComponentAdapter;
    import java.awt.event.ComponentEvent;
    import javax.swing.JScrollPane;
    
    public class ScrollableDesk extends JScrollPane {
    
        private Desk desk;
    
        /**
         * The standard constructor for the ScrollableDesk class.
         */
        public ScrollableDesk() {
            this.desk = new Desk(this);
            this.setViewportView(desk);
            this.addComponentListener(new ComponentAdapter(){
    
                @Override
                public void componentResized(ComponentEvent e) {
                    desk.adjustDimension();
                }
            });
        }
    
        /**
         * Return the desk associated with this ScrollableDesk.
         *
         * @return The desk associated with this ScrollableDesk.
         */
        public Desk getDesk() {
            return desk;
        }
    }

  2. #2
    ma questa soluzione la vedo molto poco chiara
    E' invece è molto chiara in quanto il ridimensionamento di un oggetto viene fatto dal LayoutManager e non dal componente; non avendo assegnato un layout manager ad esso non c'è modo che ti venga ridemensionato correttamente.
    La via del paintComponent non è uno spreco di risorse, ma secondo me la via da percorrere per ottenere il tuo intento.

  3. #3
    E' invece è molto chiara in quanto il ridimensionamento di un oggetto viene fatto dal LayoutManager e non dal componente; non avendo assegnato un layout manager ad esso non c'è modo che ti venga ridemensionato correttamente.
    Grazie non ci avevo pensato

    La via del paintComponent non è uno spreco di risorse, ma secondo me la via da percorrere per ottenere il tuo intento.
    Ma cosi facendo però mi ricalcola la dimensione ogni volta che esegue un repaint (parecchie volte al secondo o sbaglio?) cosa che non serve se lo scrollPane non viene ridimensionato. Se ovverriddo paintComponent allora l'ascoltatore non servirebbe a niente (anzi non serve l'ho testato XD). Forse un flag boolean isJustResized funzionerebbe per usare meno cpu? Grazie della risposta

  4. #4
    In effetti la via del paint... non è proprio la migliore.
    Potrestri aggiungere un listener al frame e intercettare il ridimensionamento di esso e da li
    comportarti di conseguenza.
    codice:
    this.addComponentListener(new ComponentAdapter() {
                public void componentResized(ComponentEvent e) {
                    // This is only called when the user releases the mouse button.
                    System.out.println("componentResized");
                }
            });

  5. #5
    Originariamente inviato da francesco.muia
    In effetti la via del paint... non è proprio la migliore.
    Potrestri aggiungere un listener al frame e intercettare il ridimensionamento di esso e da li
    comportarti di conseguenza.
    codice:
    this.addComponentListener(new ComponentAdapter() {
                public void componentResized(ComponentEvent e) {
                    // This is only called when the user releases the mouse button.
                    System.out.println("componentResized");
                }
            });
    L'ho già fatto (vedi costruttore della classe ScrollableDesk) ma viene ridisegnato correttamente solo il "tavolo" e non il "foglio". Io ho risolto ovverridando il paintComponent della classe Desk aggiungendo currentPage.adjustDimension(..) e centrePage(). In questo modo sembra funzionare, tuttavia non era necessario aggiornare ogni volta la posizione e la dimensione del foglio ogi volta che viene effettuato un repaint. Ho scelto quindi una soluzione ibrida mantenendo il listener del ridimensionamento. Il suo effetto è quello di (oltre a ridimensionare il desk) settare un flag booleano che messo in un if non fa aggiornare le dimensioni del foglio. In modo piu chiaro:
    codice:
    @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            
            if (pageNeedToRepaint) {
                currentPage.adjustDimension(this.getDimOffsetted());
                centrePage();
                pageNeedToRepaint = false;
            }
        }
    Questo mi risparmia un bel po' di risorse pur facendo andare tutto perfettamente. Se qualcuno ha una soluzione più elegante si faccia comunque avanti

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.