2012-04-29 11 views
7

Java/Eclipse IDE aquí.JButtons dentro de JPanels con GridLayout JFrame

Tengo un JFrame configurado en un GridLayout de tamaño NxN. N es dado por el usuario como una línea de comando al inicio del programa. JButtons en un patrón NxN se agregan a la ventana en JPanels, establecidos en la ubicación por GridLayout (creo).

¿Cada JButton necesita su propio JPanel para usar GridLayout? Tengo la impresión de que puede configurar solo un JPanel para todos los botones y configurar el JPanel en un GridLayout para los JButtons. Quiero agregar otro JPanel a la izquierda de la matriz de botones para mostrar los clics de los botones (JLabel) y un botón de reinicio dentro del mismo JPanel izquierdo.

Aquí es (un poco de) mi código, donde N es dada por el usuario, el sistema es mi fondo de procesos de clase, y ButtonEvent es la clase para ActionListener/actionPerformed:

JFrame window = new JFrame(""); 
GridLayout layout = new GridLayout(N,N); 
window.setLayout(layout); 

for (int row = 0; row < N; row++){ 
    for (int col = 0; col < N; col++){ 
     JPanel panel = new JPanel(); 
     JButton b = new JButton ("("+row+","+col+")"); 
     window.add(b).setLocation(row, col); 
     panel.add(b); 
     b.addActionListener(new ButtonEvent(b, system, row, col)); 
     window.add(panel); 
    } 
} 

window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
window.pack(); 
window.setVisible(true); 

y esto es lo tengo (N = 4):

http://i.imgur.com/nbQoM.png

aquí es (aproximadamente) lo que estoy buscando (N = 4):

http://i.imgur.com/SiVWO.png

Todo lo que necesito y quiero son dos (o más) JPanels que se configuran aproximadamente como arriba, y todos los administradores de diseño que he probado no juegan bien con el diseño GridLayout JFrame.

Se recomiendan todas las recomendaciones para una mejor solución.

Gracias!

Respuesta

11

Aquí prueba este código de ejemplo:

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

public class LayoutExample extends JFrame 
{ 
    private static final String INITIAL_TEXT = "Nothing Pressed"; 
    private static final String ADDED_TEXT = " was Pressed"; 
    private JLabel positionLabel; 
    private JButton resetButton; 
    private static int gridSize = 4; 

    public LayoutExample() 
    { 
     super("Layout Example"); 
    } 

    private void createAndDisplayGUI() 
    {  
     setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     JPanel contentPane = new JPanel(); 
     contentPane.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 20)); 
     contentPane.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 2)); 

     JPanel leftPanel = new JPanel(); 
     leftPanel.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 2)); 
     leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));  
     JPanel labelPanel = new JPanel(); 
     positionLabel = new JLabel(INITIAL_TEXT, JLabel.CENTER); 
     JPanel buttonLeftPanel = new JPanel(); 
     resetButton = new JButton("Reset"); 
     resetButton.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent ae) 
      { 
       positionLabel.setText(INITIAL_TEXT); 
      } 
     }); 
     labelPanel.add(positionLabel); 
     buttonLeftPanel.add(resetButton); 
     leftPanel.add(labelPanel); 
     leftPanel.add(buttonLeftPanel); 

     contentPane.add(leftPanel); 

     JPanel buttonPanel = new JPanel(); 
     buttonPanel.setLayout(new GridLayout(gridSize, gridSize, 10, 10)); 
     for (int i = 0; i < gridSize; i++) 
     { 
      for (int j = 0; j < gridSize; j++) 
      { 
       JButton button = new JButton("(" + i + ", " + j + ")"); 
       button.setActionCommand("(" + i + ", " + j + ")"); 
       button.addActionListener(new ActionListener() 
       { 
        public void actionPerformed(ActionEvent ae) 
        { 
         JButton but = (JButton) ae.getSource(); 
         positionLabel.setText(
          but.getActionCommand() + ADDED_TEXT);       
        } 
       }); 
       buttonPanel.add(button); 
      } 
     } 
     contentPane.add(buttonPanel); 

     setContentPane(contentPane); 
     pack(); 
     setLocationByPlatform(true); 
     setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     if (args.length > 0) 
     { 
      gridSize = Integer.parseInt(args[0]); 
     } 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       new LayoutExample().createAndDisplayGUI(); 
      } 
     }); 
    } 
} 

SALIDA:

Start After Click

+1

+1 Consulte también este [ejemplo] relacionado (http://stackoverflow.com/a/7706684/230513). – trashgod

+1

@trashgod: Gracias por eliminar ese gran error, ya que ahora al menos se ejecutará, incluso sin proporcionar ningún argumento :-). Mi cheque antes era inútil, LOL. –

+0

¡Agradable! Me gusta cómo esto se reajusta (o, en realidad, no cambia de tamaño). La publicación de trashgod a continuación explica exactamente por qué funciona así. ¡Gracias! – Avertheus

7

¿Cada JButton necesita su propio JPanel para usar GridLayout?

No. Agregar y configurarLayout en JFrame no hace lo que parece. JFrame es Top-Level Containers y es mejor organizar tu contenido en JPanels.

Debe organizar los paneles en esa forma:

----JPanel----------------------------| 
| ---LeftPanel--- ---ButtonsPanel--- | 
| |    | |    | | 
| |    | |    | | 
| |    | | GridLayout(N,N)| | 
| |    | |    | | 
| |    | |    | | 
| --------------- ------------------ | 
--------------------------------------- 

A continuación, agregue JPanel al JFrame. poner también paneles en clases separadas:

class BPanel extends JPanel { 
    public BPanel() { 
     GridLayout layout = new GridLayout(N,N, hgap, vgap); 
     setLayout(layout); 
     for (int row = 0; row < N; row++){ 
      for (int col = 0; col < N; col++){ 
       JButton b = new JButton ("("+row+","+col+")"); 
       add(b).setLocation(row, col); 
       b.addActionListener(new ButtonEvent(b, system, row, col)); 
      } 
     } 
    } 
} 
class LeftPanel extends JPanel { 
.... 
} 

class MainFrame extends JFrame { 
    public MainFrame() { 
     JPanel p = new JPanel(); 
     p.add(new LeftPanel()); 
     p.add(newButtonsPanel()); 
     add(p); 
    } 
} 
+1

Nice answer. Gran arte ASCII! Ver también el [Ejemplo de diseño anidado] (http://stackoverflow.com/a/5630271/418556). –

+0

Sí, esto parece haber funcionado para mí. Tengo todos mis JPanels en diferentes clases ahora, y un solo JPanel para GridLayout. ¡Gracias por la explicación! – Avertheus

3

Una ventaja de dar a cada botón (o grupo de botones) su propio panel es que el panel anidado puede tener un diseño diferente En este example, cada ButtonPanel anidado tiene el valor predeterminado FlowLayout, por lo que el tamaño del botón permanece constante a medida que se cambia el tamaño del contenedor circundante.

+0

Eso es interesante, de hecho, eso es lo que me di cuenta, cuando leí la primera respuesta a este hilo de @ixos, así que por diversión, me senté para hacer lo que OP quería, y me di cuenta de que este asunto del 'aspecto de tamaño' está causando problemas en el 'Panel izquierdo', por eso esos dos separan 'JPanel's para' JButton' y 'JLabel ', pero lo que sugirió que para cada' JButton' a 'JPanel', me gustó esto :-) –

Cuestiones relacionadas