PDA

View Full Version : [JAVA] Layout ridimensionabili


franksisca
07-10-2006, 11:41
Ragazzi, come faccio a fare in modo da rendere i layout ridimensionabili secondo preferenza dell'utente???

mi spiego meglio, vedete ad esempio quando aprite i preferiti su firefox....bene, se mettete il cursore sul bordo, lui cambia forma e vi permette di ridimensionare la larghezzza.

Sarebbe possibile fare una cosa del genere con i layout(tipo Border Layout)o con un qualsiasi altro layout???

se devo reimplementarne uno mio, come faccio a permettere questa operazione???

lovaz
07-10-2006, 12:28
Intendi uno split pane?

Qui vedi come è fatto (la foto dell'astronauta):
http://java.sun.com/docs/books/tutorial/uiswing/components/components.html

franksisca
07-10-2006, 12:33
Intendi uno split pane?

Qui vedi come è fatto (la foto dell'astronauta):
http://java.sun.com/docs/books/tutorial/uiswing/components/components.html
esatto, una cosa del genere........sai come è fatto quello???

PGI-Bis
07-10-2006, 13:31
I partecipanti al fattaccio sono due: il contenuto ed il suo contenitore. Il contenitore è responsabile della gestione degli eventi del mouse che determinano il ridimensionamento e il contenuto stabilisce le informazioni necessarie affinchè ridimensionamento vi sia e di quanto.

Al minimo ti serve un LayoutManager, un Container e un Component.

Ti faccio un esempio che, per pigrizia, ricicla il LayoutManager FlowLayout, con ancoraggio FlowLayout.LEFT. Il FlowLayout "va bene" perchè rispetta le dimensioni preferite del contenuto e l'ancoraggio a sinistra ti permette di lavorare sul componente disponendo di un'origine immutabile.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;

public class ResizableComponent extends JPanel {
private Cursor plainCursor;
private final Cursor RESIZE_CURSOR = Cursor.getPredefinedCursor(
Cursor.W_RESIZE_CURSOR);

/** Punto di ancoraggio del trascinamento. E' usato sia per calcolare la
quantità di spostamento che per determinare se sia in corso il
trascinamento */
private Point dragStart;

/** Adattatore Mouse connesso al contenitore di questo componente */
private MouseInputAdapter mouseHook = new MouseInputAdapter() {
/** Cambia i cursori */
public void mouseMoved(MouseEvent e) {
if(nearBorder(e.getPoint(), getBounds())) {
setResizeCursor();
} else {
setPlainCursor();
}
}

/** Inizia le operazioni di trascinamento */
public void mousePressed(MouseEvent e) {
if(nearBorder(e.getPoint(), getBounds())) {
startResize(e.getPoint());
}
}

/** Trascinamento: ridimensiona il componente */
public void mouseDragged(MouseEvent e) {
if(dragStart != null) {
resize(e.getPoint());
}
}

/** Ferma le operazioni di trascinamento */
public void mouseReleased(MouseEvent e) {
dragStart = null;
}
};

/** Invocato se il mouse sia premuto in un punto del contenitore valido
per il ridimensionamento di questo componente */
private void startResize(Point p) {
dragStart = p;
}

/** Ridimensiona questo componente: "quanto" è determinato dallo
spostamento subito dal mouse */
private void resize(Point p) {
int dx = p.x - dragStart.x;
dragStart = p;
Dimension size = getSize();
size.width += dx;
setPreferredSize(size);
revalidate();
}

/** Ferma le operazioni di trascinamento */
private void stopResize() {
dragStart = null;
}

/** Determina se il mouse si trovi più o meno in corrispondenza del bordo
[destro] di questo componente */
private boolean nearBorder(Point p, Rectangle bounds) {
return
p.x >= bounds.x + bounds.width - 2 &&
p.x <= bounds.x + bounds.width + 2;
}

/** Applica il cursore di ridimensionamento al contenitore di questo
componente */
private void setResizeCursor() {
Component parent = getParent();
if(parent != null && parent.getCursor() != RESIZE_CURSOR) {
plainCursor = parent.getCursor();
parent.setCursor(RESIZE_CURSOR);
}
}

/** Applica il cursore "normale" al contenitore di questo componente */
private void setPlainCursor() {
Component parent = getParent();
if(parent != null) {
parent.setCursor(plainCursor);
}
}

/** Costruttore */
public ResizableComponent() {
setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
setBackground(Color.RED);
setOpaque(true);
setPreferredSize(new Dimension(100, 100));
}

/** Quando questo componente riceve una notifica di inserimento, dopo aver
condotto le normali operazioni stabilite dal framework, rifila al suo
contenitore l'adattatore mouseHook */
public void addNotify() {
super.addNotify();
Component parent = getParent();
if(parent != null) {
parent.removeMouseListener(mouseHook);
parent.removeMouseMotionListener(mouseHook);
parent.addMouseListener(mouseHook);
parent.addMouseMotionListener(mouseHook);
}
}
}

Il resto l'ho messo nel Main ma considera che anche come è fatto questo "resto" è determinante:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;

public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Main().startUI();
}
});
}

private void startUI() {
JPanel container = new JPanel();
container.setPreferredSize(new Dimension(400, 400));
container.setLayout(new FlowLayout(FlowLayout.LEFT));
container.add(new ResizableComponent());
JFrame frame = new JFrame("Resiza sample");
frame.setContentPane(container);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}

Nota come l'attribuzione delle dimensioni al componente sia "assoluta": un componente può allargarsi di un milione di pixel. JSplitPane funziona in modo simile solo che assegna ai componenti una nuova dimensione determinata come percentuale dello spazio assegnato al contenitore: questo impedisce ad un componente di assumere larghezze o altezze che fuoriescano dalla regione di spazio assegnata al contenitore.

PGI-Bis
07-10-2006, 13:33
Il codice riportato è solo un esempio della "meccanica rilevate": ci sono un tot di controlli da eseguire – un componente non accetta dimensioni negative, è presupposto un ridimensionamento orizzontale causato da un trascinamento del lato "destro" – ma quello che manca dovrebbe essere evidente.

franksisca
07-10-2006, 14:12
ok, grazie, se ho problemi ti rompo le scatole