2010-01-21 7 views
29

Quando un utente fa clic sull'angolo di una JFrame per ridimensionare e trascinare il mouse, il JFrame ridisegna in base alla posizione corrente del mouse mentre l'utente trascina. Come puoi ascoltare questi eventi?Ascolta gli eventi di ridimensionamento JFrame mentre l'utente trascina il mouse?

riportano di seguito le quello che ho attualmente provato:

public final class TestFrame extends JFrame { 
    public TestFrame() { 
     this.addComponentListener(new ComponentAdapter() { 
      public void componentResized(ComponentEvent e) { 
       // This is only called when the user releases the mouse button. 
       System.out.println("componentResized"); 
      } 
     }); 
    } 

    // These methods do not appear to be called at all when a JFrame 
    // is being resized. 
    @Override 
    public void setSize(int width, int height) { 
     System.out.println("setSize"); 
    } 

    @Override 
    public void setBounds(Rectangle r) { 
     System.out.println("setBounds A"); 
    } 

    @Override 
    public void setBounds(int x, int y, int width, int height) { 
     System.out.println("setBounds B"); 
    } 
} 

Come posso determinare e vincolare come l'utente ridimensiona una finestra (in base al rapporto di aspetto attuale della finestra) in quanto sono trascinando il mouse in giro?

+0

@finnw puoi chiarire la ragione del tuo Bounty, perché vedo differenza tra 'Java_1.4' e' Java_1.5', ma non riesco a trovare diference per 'Java_6',' note' ma senza il più profondo controllando in 'Nested' e' Inherits Method' – mKorbel

+0

@mKorbel, ho provato entrambi i metodi (ComponentListener su JPanel; Override validate.) Il codice viene compilato ed eseguito in entrambe le versioni di Java ma in Java 1.6 il layout viene ricalcolato continuamente, ma in Java 1.5 solo quando rilascio il mouse. – finnw

+0

@finnw stai ridimensionando JComponent o JFrame – mKorbel

risposta

7

Probabilmente è necessario eseguire l'override di qualcosa come validate (non dimenticare di chiamare il super). Naturalmente, potrebbe non funzionare se si utilizza un sistema di finestre per configurare il trascinamento dei contorni.

+0

Come dovrei chiamare il super per questo? Ho pensato che potevi chiamare super in un costruttore? –

+3

Whoops, trovato. super.validate(), ovviamente. –

37

È possibile aggiungere un ascoltatore componenti e implementare la funzione componentResized così:

JFrame component = new JFrame("My Frame"); 

component.addComponentListener(new ComponentAdapter() 
{ 
     public void componentResized(ComponentEvent evt) { 
      Component c = (Component)evt.getSource(); 
      //........ 
     } 
}); 

EDIT: A quanto pare, per JFrame, l'evento componentResized è agganciato alla manifestazione mouseReleased. Ecco perché il metodo viene richiamato quando viene rilasciato il pulsante del mouse.

Un modo per ottenere quello che vuoi è aggiungere un JPanel che copra l'intera area del tuo JFame. Quindi aggiungi componentListener a JPanel (ComponentResized per JPanel viene chiamato anche mentre il mouse sta ancora trascinando). Quando la cornice viene ridimensionata, anche il pannello verrà ridimensionato.

Lo so, questa non è la soluzione più elegante, ma funziona!

+0

Grazie per la pronta risposta. Tuttavia, ComponentResized sembra essere chiamato solo quando l'utente rilascia il pulsante del mouse. È possibile ascoltare gli eventi di ridimensionamento * come * l'utente sta trascinando il mouse? – Clinton

+0

@Clinton Vero! Mi dispiace, non ho letto attentamente la tua domanda! – Alex

+0

@Clinton Ero curioso di sapere come farlo e l'unico modo che ho trovato è stato aggiungere un JPanel nella JFrame. Non so se questo ti aiuta. Ho aggiornato la mia risposta. – Alex

-2
public class MouseDrag extends Component implements MouseListener, 
    MouseMotionListener { 
    /** The Image we are to paint */ 
    Image curImage; 

    /** Kludge for showStatus */ 
    static Label status; 

    /** true if we are in drag */ 
    boolean inDrag = false; 

    /** starting location of a drag */ 
    int startX = -1, startY = -1; 

    /** current location of a drag */ 
    int curX = -1, curY = -1; 

    // "main" method 
    public static void main(String[] av) { 
    JFrame f = new JFrame("Mouse Dragger"); 
    Container cp = f.getContentPane(); 

    if (av.length < 1) { 
     System.err.println("Usage: MouseDrag imagefile"); 
     System.exit(1); 
    } 
    Image im = Toolkit.getDefaultToolkit().getImage(av[0]); 

    // create a MouseDrag object 
    MouseDrag j = new MouseDrag(im); 

    cp.setLayout(new BorderLayout()); 
    cp.add(BorderLayout.NORTH, new Label(
     "Hello, and welcome to the world of Java")); 
    cp.add(BorderLayout.CENTER, j); 
    cp.add(BorderLayout.SOUTH, status = new Label()); 
    status.setSize(f.getSize().width, status.getSize().height); 
    f.pack(); 
    f.setVisible(true); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    // "Constructor" - creates the object 
    public MouseDrag(Image i) { 
    super(); 
    curImage = i; 
    setSize(300, 200); 
    addMouseListener(this); 
    addMouseMotionListener(this); 
    } 

    public void showStatus(String s) { 
    status.setText(s); 
    } 

    // Five methods from MouseListener: 
    /** Called when the mouse has been clicked on a component. */ 
    public void mouseClicked(MouseEvent e) { 
    } 

    /** Called when the mouse enters a component. */ 
    public void mouseEntered(MouseEvent e) { 
    } 

    /** Called when the mouse exits a component. */ 
    public void mouseExited(MouseEvent e) { 
    } 


    // And two methods from MouseMotionListener: 
    public void mouseDragged(MouseEvent e) { 
    Point p = e.getPoint(); 
    // System.err.println("mouse drag to " + p); 
    showStatus("mouse Dragged to " + p); 
    curX = p.x; 
    curY = p.y; 
    if (inDrag) { 
     repaint(); 
    } 
    } 

    public void paint(Graphics g) { 
    int w = curX - startX, h = curY - startY; 
    Dimension d = getSize(); 
    g.drawImage(curImage, 0, 0, d.width, d.height, this); 
    if (startX < 0 || startY < 0) 
     return; 
    System.err.println("paint:drawRect @[" + startX + "," + startY 
     + "] size " + w + "x" + h); 
    g.setColor(Color.red); 
    g.fillRect(startX, startY, w, h); 
    } 

} 
+2

-1. Questo è fondamentalmente un duplicato del codice nella domanda (che abbiamo già sapere non risolve il problema.) – finnw

6

Un'altra soluzione (che è molto simile a quella di Alex, ma un po 'più semplice) è quello di ascoltare gli eventi dal pannello principale s' il JFrame invece:

public final class TestFrame extends JFrame { 
    public TestFrame() { 
     this.getRootPane().addComponentListener(new ComponentAdapter() { 
      public void componentResized(ComponentEvent e) { 
       // This is only called when the user releases the mouse button. 
       System.out.println("componentResized"); 
      } 
     }); 
    } 
} 

A seconda di altri dettagli di implementazione, è possibile che il pannello radice possa essere cambiato. Se questa è una possibilità, puoi sostituire lo setRootPane() e gestirlo. Poiché setRootPane() è protetto e tuttavia chiamato solo dal costruttore, è improbabile che sia necessario farlo.

+0

Non dovrebbe essere 'public public TestFrame() {' ...? –

+2

@AnnonomusPenguin, no, questa è una dichiarazione costruttore, e i costruttori non specificano tipi di ritorno come 'void'. –

Problemi correlati