Avete idea se è possibile ricreare l' "effetto calamita" che si osserva in molti programmi quando si dispongono le loro finestre? Vorrei cercare di aggiungerlo ad un JDesktopPane che contiene molti frame interni.
Avete idea se è possibile ricreare l' "effetto calamita" che si osserva in molti programmi quando si dispongono le loro finestre? Vorrei cercare di aggiungerlo ad un JDesktopPane che contiene molti frame interni.
Te lo devi creare a mano.
Implementare un ComponentListener che controlla se il JInternalFrame a cui è registrato raggiunge una certa distanza minima dal bordo della finestra principale. In tal caso, il JInternalFrame viene automaticamente attaccato al bordo.
Ciao.![]()
"Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza
Questo codice che ho scritto al volo, ad esempio, crea un semplice effetto calamita quando il JInternalFrame è a 20 pixel dal bordo destro.
Ciao.codice:import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Calamita extends JFrame { private class Interno extends JInternalFrame { public Interno() { setSize(300, 300); setTitle("Titolo"); setVisible(true); } } private class CL extends ComponentAdapter { private Component p; public CL(Component p) { this.p = p; } public void componentMoved(ComponentEvent ce) { Component c = ce.getComponent(); if (c.getLocation().x+c.getBounds().width >= p.getBounds().width-20) { c.setLocation( p.getBounds().width-c.getBounds().width-2, c.getLocation().y); } p.repaint(); } } private JDesktopPane jdp; private Interno interno; public Calamita() { jdp = new JDesktopPane(); setContentPane( jdp ); interno = new Interno(); interno.addComponentListener( new CL(this) ); jdp.add( interno ); setTitle("Titolo esterno"); setSize(800, 600); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); } public static void main(String [] args) { Calamita c = new Calamita(); } }![]()
"Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza
Esatto! Ho capito come fare, ma rimane il problema che si vede un fastidioso susseguirsi di repaint...
In pratica si vede il frame che viene dipinto nel suo posto originale e poi ridipinto col bordo attaccato al muro.
Penso sia perchè prima viene chiamato il paint() normale del componente e poi viene chiamato il repaint() dal codice che hai scritto.
Bisognerebbe impedire al componente di fare il suo paint() ad ogni movimento del mouse quando ci si trova in prossimità dei bordi... e quindi sovrascrivere qualche metodo di Component proprio?
Ora dò un'occhiata agli API...
Ho fatto un pò di controlli e ho visto che muovendo il frame interno il metodo che viene chiamato è il repaint(). Quindi mi son concentrato su quello.
Una possibile soluzione che ho trovato è sovrascrivere appunto il metodo di repaint() del JInternalFrame, controllando nella sua nuova implementazione se il frame si trova in prossimità del bordo.
A quel punto se il frame si trova in prossimità del bordo, uso setLocation() e lo metto attaccato al bordo.
Semplice! MA il problema è che setLocation chiama al suo interno il repaint()!!!!!
Quindi si genera ricorsione indiretta, e le cose implodono in un ciclo infinito.
Non riesco però a trovare un metodo per settare la locazione di un JInternalFrame SENZA che questo richiami il repaint()!
Yhuu penso di aver risolto. Ecco il metodo repaint() nella sua nuova implementazione. La variabile frame è il riferimento al frame principale che contiene tutto.
codice:public void repaint() { if (frame == null) { return; } // siamo vicino al bordo if ((this.getLocation().x + this.getBounds().width >= frame.getBounds().width - 20) &&(this.getLocation().x + this.getBounds().width <= frame.getBounds().width +20)) { // se siamo proprio sul bordo if(this.getLocation().x + this.getBounds().width == frame.getBounds().width) { super.repaint(); frame.repaint(); } else { this.setLocation( frame.getBounds().width - this.getBounds().width, this.getLocation().y); } } // non siamo vicini al bordo else { super.repaint(); frame.repaint(); } }
Grazie a LeleFT![]()