Utilizzando GridBagLayout in un JLayeredPane
-
26-10-2019 - |
Domanda
Sto tentando di avere un piccolo galleggiante "widget di" di sorta in alto a destra di un JPanel. Si tratta di un componente di dimensioni fisse -. Pensare alla bussola in una sorta di Google Maps di vista, se questo aiuta ??p>
Mi rendo conto che JLayeredPane utilizza solo un gestore di layout per tutti i livelli e così abbiamo pensato che l'utilizzo di GBL con avere successo: - rendere alto a destra (1, 0) scatola molto piccola e mettere il widget di lì - rendere il pannello di contenuti sia di larghezza / altezza 2
Ma dopo la sperimentazione, sembra che GBL rimuove alcuni componenti quando si sovrappongono.
Qualcuno può suggerire un modo di falsificare questo comportamento?
Soluzione
E ' stratificato riquadro, e così ogni strato può avere un contenitore che utilizza una sua disposizione, se desiderato. Non darei la stessa JLayeredPane qualsiasi layout, ma piuttosto utilizzare il layout predefinito nullo e quindi potrebbe valutare l'ipotesi piccolo galleggiante di widget in modo trasparente (non opaco) JPanel che utilizza qualsiasi layout desiderato e aggiungere i JPanel trasparenti ad una tomaia strato della JLayeredPane.
Per esempio questo codice mette un'immagine di una bussola in alto a destra di un JPanel non opachi che è stratificato su un JLabel che mostra un plastico:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")
public class LayeredExample extends JLayeredPane {
public static final String MAP_URL = "http://upload.wikimedia.org/" +
"wikipedia/commons/c/c4/Maps-for-free_Sierra_Nevada.png";
public static final String COMPASS_URL = "http://upload.wikimedia.org/" +
"wikipedia/commons/thumb/f/f8/Compass_Rose_English_North.svg/" +
"200px-Compass_Rose_English_North.svg.png";
private Dimension imageSize;
private JLabel defaultLabel = new JLabel();
private JPanel palettePane = new JPanel();
private JLabel compassLabel = new JLabel();
public LayeredExample() {
try {
URL mapUrl = new URL(MAP_URL);
BufferedImage mapImage = ImageIO.read(mapUrl);
ImageIcon mapIcon = new ImageIcon(mapImage);
defaultLabel.setIcon(mapIcon);
URL compassUrl = new URL(COMPASS_URL);
BufferedImage compassImage = ImageIO.read(compassUrl);
ImageIcon compassIcon = new ImageIcon(compassImage);
compassLabel.setIcon(compassIcon);
imageSize = new Dimension(mapImage.getWidth(), mapImage.getHeight());
setPreferredSize(imageSize);
defaultLabel.setSize(imageSize);
defaultLabel.setLocation(0, 0);
palettePane.setSize(imageSize);
palettePane.setLocation(0, 0);
JPanel northPalettePane = new JPanel(new BorderLayout());
northPalettePane.setOpaque(false);
northPalettePane.add(compassLabel, BorderLayout.EAST);
palettePane.setOpaque(false);
palettePane.setLayout(new BorderLayout());
palettePane.add(northPalettePane, BorderLayout.NORTH);
add(defaultLabel, JLayeredPane.DEFAULT_LAYER);
add(palettePane, JLayeredPane.PALETTE_LAYER);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void createAndShowUI() {
JFrame frame = new JFrame("LayeredExample");
frame.getContentPane().add(new LayeredExample());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
Altri suggerimenti
In alternativa, si consideri javax.swing.OverlayLayout
. Ecco alcuni esempi .