2017-10-16 5 views
1

Le problème: Je n'ai aucun contrôle sur l'implémentation de plus dans le paquet d'histogrammes, donc je crée un tableau de boutons et les superpose au-dessus de l'histogramme en utilisant JLayeredPane. Cependant, je ne peux pas mettre à l'échelle l'histogramme et les panneaux de boutons lorsque le JFrame est agrandi ou réduit. Le JLayedPane est composé de 2 JPanels, voir MWE. Pour répéter le problème, exécutez simplement le programme et étendez JFrame.JLayeredPane avec JPanel

J'ai lu ce qui suit sur les poteaux SO; jlayeredpane-with-gridlayout, jlayeredpane-with-a-layoutmanager, jlayeredpane-not-resizing-with-jframe, resize-jframe-to-jpanels-inside-jlayeredpane, automatic-content-resizing-of-jlayeredpane, ainsi que la Oracle page on JLayeredPane qui a quelques exemples

Aussi utile que ces liens étaient, je ne peux toujours pas obtenir les deux JPanels d'étendre/contrat avec le JFrame. Question: Existe-t-il un moyen d'actualiser les deux JPanels dans JLayeredPane sans implémenter une nouvelle mise en page? Si une nouvelle mise en page est nécessaire, quelqu'un pourrait-il fournir un MWE sur la façon de le faire?

public class FrameDemo extends JPanel { 

    private JLayeredPane layeredPane; 
    private final int width = 800; 
    private final int height = 800; 
    private String[] layerStrings = { "Yellow (0)", "Magenta (1)", "Cyan (2)", "Red (3)", "Green (4)", "Blue (5)" }; 
    private Color[] layerColors = { Color.yellow, Color.magenta, Color.cyan, Color.red, Color.green, Color.blue }; 

    public FrameDemo() { 
     setLayout(new BorderLayout()); 
     init(); 
     addPanels(); 
     add(layeredPane, BorderLayout.CENTER); 
    } 

    private void init() { 
     this.layeredPane = new JLayeredPane(); 
     this.layeredPane.setPreferredSize(new Dimension(width, height)); 
     this.layeredPane.setBorder(BorderFactory.createTitledBorder("Histogram should go here")); 
     this.layeredPane.setLayout(new BorderLayout()); 

    } 

    private void addPanels() { 
     this.layeredPane.add(createHistogramPanel(), BorderLayout.CENTER, new Integer(1)); 
     this.layeredPane.add(createButtonPanel(), BorderLayout.CENTER, new Integer(0)); 
     this.layeredPane.addComponentListener(new ComponentAdapter() { 
     @Override 
     public void componentResized(ComponentEvent e) { 
      Dimension size = layeredPane.getSize(); // get size 
      createHistogramPanel().setSize(size); // push size through 
      createButtonPanel().setSize(size); // push size trhough 
      // otherChildOfLayers.setSize(size); // push size trhough 
      layeredPane.revalidate(); // revalidate to see updates 
      layeredPane.repaint(); // "Always invoke repaint after 
            // revalidate" 
     } 
    }); 
    } 

    private JPanel createHistogramPanel() { 

     JPanel histpanel = new JPanel(); 

     histpanel.setLayout(new GridLayout(2, 3)); 
     for (int i = 0; i < layerStrings.length; i++) { 
      JLabel label = createColoredLabel(layerStrings[i], layerColors[i]); 
      histpanel.add(label); 
     } 
     histpanel.setOpaque(false); 
     histpanel.setBounds(10, 10, width, height); 
     return histpanel; 
    } 

    private JLabel createColoredLabel(String text, Color color) { 
     JLabel label = new JLabel(""); 
     label.setVerticalAlignment(JLabel.TOP); 
     label.setHorizontalAlignment(JLabel.CENTER); 
     label.setOpaque(true); 
     label.setBackground(color); 
     label.setForeground(Color.black); 
     label.setBorder(BorderFactory.createLineBorder(Color.black)); 
     label.setPreferredSize(new Dimension(120, 120)); 
     return label; 
    } 

    private JPanel createButtonPanel() { 
     ButtonGroup buttons = new ButtonGroup(); 

     JPanel buttonPanel = new JPanel(); 
     buttonPanel.setLayout(new GridLayout(2, 3)); 
     for (int i = 0; i < 6; i++) { 
      final int placer = i + 1; 
      JButton freshButton = new JButton(); 
      freshButton.addActionListener(e -> { 
       System.out.println("Button " + placer + " clicked"); 
      }); 

      freshButton.setText("Button " + (i + 1)); 
      freshButton.setOpaque(true); 
      freshButton.setContentAreaFilled(false); 
      freshButton.setBorderPainted(false); 
      freshButton.setBounds(new Rectangle(132, 75 + (i * 20), 40, 20)); 
      buttonPanel.add(freshButton, null); 
      buttons.add(freshButton); 

     } 
     buttonPanel.setOpaque(false); 

     buttonPanel.setBounds(10, 10, width, height); 
     return buttonPanel; 
    } 

    private static void createAndShowGUI() { 
     JFrame frame = new JFrame("Testing"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JComponent newContentPane = new FrameDemo(); 
     newContentPane.setOpaque(true); // content panes must be opaque 
     frame.setContentPane(newContentPane); 
     frame.setLocationRelativeTo(null); 

     frame.pack(); 

     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 

} 
+0

Je suggère de supprimer le premier paragraphe et celui sur les pots de votre question. Il n'ajoute rien pour comprendre le problème spécifique. –

+0

Cela ressemble au même problème que décrit dans https://stackoverflow.com/questions/24522151/jlayeredpane-not-resizing-with-jframe Comme vous l'avez déjà mentionné, qu'est-ce qui est différent de votre problème? La réponse proposant de mettre à jour la taille avec un module d'écoute pour 'componentResized' pourrait-elle également vous convenir? –

+0

J'ai essayé la solution sur le poste, à savoir addComponentListener, vous avez mentionné, mais cela n'a pas résolu le problème. C'est pourquoi je ne l'ai pas inclus dans le MWE. J'ai édité mon MWE pour montrer que cette solution ne fonctionne pas. – mkunkel

Répondre

1

Votre code ne fonctionnera pas parce que dans componentResized vous créez nouveaux panneaux et appliquer la taille à leur disposition. Vous devez redimensionner les panneaux existants ajoutés au volet en couches. Cela peut être fait en affectant histogramPanel et buttonPanel comme variables d'instance.

+0

J'ai aussi essayé d'en faire des variables d'instance et j'ai eu de la chance pour résoudre le problème de cette façon. – mkunkel